4 Entities and attributes
This chapter moves from requirements gathering into the design and analysis phase, focusing on data modeling to produce an entity-relationship diagram for The Sci‑Fi Collective’s online store. It explains how to turn subjects and their characteristics into entities and attributes, emphasizing clear, consistent naming. The chapter recommends singular names for entities and a consistent attribute style (such as snake_case), and advises checking for overly long identifiers and avoiding reserved SQL keywords by renaming them when necessary (for example, replacing a word like “order” with “purchase”). The result is a coherent set of entities and attributes ready for the next stages of database design.
The chapter then concentrates on keys—defining superkeys, candidate keys, and primary keys—and offers a practical method to identify and choose among candidate keys using criteria such as uniqueness, non-nullability, stability, simplicity, familiarity, length, and performance. Through concrete examples, it shows how email is selected as the user table’s primary key over username or phone number due to stability, and why a product_code is preferred to a composite of name and manufacturer. When no satisfactory natural key exists, the chapter advocates introducing a surrogate key (for example, auto-increment IDs like review_id, payment_id, and purchase_id), noting that in some tables controlled redundancy is acceptable or even expected while uniqueness of row identity remains paramount.
Finally, the chapter establishes data types for all attributes. It outlines guidelines for string types (CHAR for fixed-length, VARCHAR for variable but bounded length, TEXT for large free text) and cautions about performance and length declarations, as well as the importance of character sets. It covers integer types of different sizes and the signed/unsigned choice, and explains why seemingly numeric values such as card_number, expiry_date, and UPC-like product codes should be stored as strings to preserve leading zeros. For monetary values, it recommends fixed-point types (DECIMAL with appropriate precision and scale) over floating-point to avoid rounding errors. It concludes with temporal types (DATE, TIME, DATETIME, TIMESTAMP), recommending TIMESTAMP for cross-time-zone events and storing times in UTC for consistency, while reminding readers that specific data type names and behaviors can vary across RDBMS and may require small adjustments.
Summary
- Design of an entity requires identification of all its attributes, the primary key, and data types of all its attributes.
- A primary key should be able to identify each row uniquely in a table. Depending on your case, you may need a primary key to be able to prevent redundancies. If there are no candidate keys available, or none of the candidate keys are a good fit for the primary key, you can always create a numeric attribute and use it as the primary key.
- Some common data types in databases include string types, integer types, decimal types, and temporal types. When it comes to deciding which data type to use, you need to think about what job a data type is good for as well as the demand of your particular case.
- Given an attribute, to identify its data type, you need to examine the sample data and the gathered information from the requirements gathering phase, identify the proper data type group (e.g., string), and choose the best fit within that group (e.g., TEXT) based on the maximum allowed values or spaces derived from your requirements analysis.
- The use of proper data types ensures that a database stores data efficiently as well as meets the demands of data querying.
FAQ
What are entities and attributes in relational database design?
Entities are distinct things or concepts you want to store data about (for example, user, product, purchase). Attributes are the properties that describe an entity (for example, username, email, product_name, price). In practice, you turn the subjects and characteristics gathered from requirements into entities and their attributes, then refine names and data types during design.Should I name tables and columns in singular or plural?
Pick one convention and be consistent. Many designers prefer singular (user, product) because it aligns with object-oriented thinking and avoids ambiguity in queries. Others like plural (users, products) because tables store sets. The key is consistency; this chapter uses singular names.What attribute naming conventions work best?
Any consistent, readable convention works. Common choices include:- snake_case (first_name)
- camelCase (firstName)
- PascalCase (FirstName)
- UPPER_CASE (FIRST_NAME)
- Hungarian/semantic prefixes (strFirstName, customerName)
What naming pitfalls should I avoid (length limits and reserved words)?
Two big checks:- Length limits: Most RDBMS cap identifier length (for example, 64 chars in MariaDB). Shorten overly long names.
- Reserved keywords: Don’t use SQL keywords as identifiers (for example, SELECT, ORDER, JOIN). If you have a clash (for example, an entity named ORDER), rename it (for example, purchase) to prevent syntax and maintenance issues.
What’s the difference among superkeys, candidate keys, and a primary key?
- Superkey: Any set of one or more attributes that uniquely identifies a row (may include extra, unnecessary attributes).
- Candidate key: A minimal superkey (no unnecessary attributes).
- Primary key: The single candidate key chosen to uniquely identify rows in the table.
How do I choose a primary key when multiple candidate keys exist?
Evaluate candidates on factors like uniqueness, non-nullability, stability (rarely changes), simplicity, shortness, familiarity, and performance. Example: In a user table, username, email, and phone_number may all be candidate keys; choosing email could be best if it’s more stable (usernames might change) and still unique/non-null.When should I use a surrogate key (auto-increment ID)?
Use a surrogate key when:- No natural candidate key exists or none is suitable (for example, review_text + review_time isn’t reliably unique).
- Uniqueness is more important than deduplication (for example, payment_method, purchase). Surrogate keys ensure unique row identification and typically improve performance and scalability.
How do I choose between CHAR, VARCHAR, and TEXT for strings?
- CHAR(n): Fixed-length strings; good for uniform-length data (for example, state codes). Example: CHAR(2).
- VARCHAR(n): Variable-length strings with a clear upper bound (for example, names, emails). Example: VARCHAR(30), VARCHAR(255).
- TEXT: Large, variable text with hard-to-predict maximums (for example, product descriptions). Use sparingly; may be stored off-row and can impact performance/indexing.
How should I pick numeric types (integers vs decimals vs floats)?
- Integers: TINYINT, SMALLINT, INT, BIGINT (choose the smallest that fits your max value; use UNSIGNED for IDs). Example: INT UNSIGNED for auto-increment keys.
- Decimals (fixed-point): DECIMAL(p,s) or NUMERIC for money and any values requiring exact precision. Example: price DECIMAL(7,2), total_price DECIMAL(13,2).
- Floats (FLOAT/DOUBLE): For approximate values where small rounding errors are acceptable (for example, sensor data). Avoid for currency.
- Numeric-looking but not numeric: Store identifiers that can have leading zeros or no math (for example, card_number, UPC) as strings (for example, CHAR(16), CHAR(12)).
Which temporal data types should I use, and how do I handle time zones?
- DATE: Date only (for example, birthdays).
- TIME: Time of day only.
- DATETIME: Local date and time without timezone conversion.
- TIMESTAMP: Moment-in-time stored/converted consistently across time zones; great for created/updated times, events.
Grokking Relational Database Design ebook for free