+ "source": "## Enums vs. Lookup Tables for Valid Values\n\nIn the `Enrollment` example above, we used an **enum** to restrict `grade` to valid values: `enum('A', 'B', 'C', 'D', 'F', 'IP')`.\nAn alternative approach uses a **lookup table** to define valid grades.\n\nBoth approaches enforce data integrity, but they have different trade-offs:\n\n`````{tab-set}\n````{tab-item} Using Enum\n:sync: enum\n```python\n@schema\nclass Enrollment(dj.Manual):\n definition = \"\"\"\n -> Student\n -> Course\n ---\n enrollment_date : date\n grade : enum('A', 'B', 'C', 'D', 'F', 'IP')\n \"\"\"\n```\n````\n````{tab-item} Using Lookup Table\n:sync: lookup\n```python\n@schema\nclass LetterGrade(dj.Lookup):\n definition = \"\"\"\n grade : char(2)\n ---\n grade_point = null : decimal(3,2)\n description : varchar(30)\n \"\"\"\n contents = [\n ('A', 4.00, 'Excellent'),\n ('B', 3.00, 'Good'),\n ('C', 2.00, 'Satisfactory'),\n ('D', 1.00, 'Passing'),\n ('F', 0.00, 'Failing'),\n ('IP', None, 'In Progress'),\n ]\n\n@schema\nclass EnrollmentWithLookup(dj.Manual):\n definition = \"\"\"\n -> Student\n -> Course\n ---\n enrollment_date : date\n -> LetterGrade\n \"\"\"\n```\n````\n`````\n\n```{list-table} Enum vs. Lookup Table Comparison\n:header-rows: 1\n:widths: 15 42 43\n\n* - Aspect\n - Enum\n - Lookup Table\n* - **Associated data**\n - Cannot store additional attributes (e.g., grade points)\n - Can include related data like grade points, descriptions\n* - **Modifications**\n - Requires `ALTER TABLE` to add/remove values\n - Add or remove rows without schema changes\n* - **Querying**\n - Values are inline; no join needed\n - Requires join to access the value or related data\n* - **Referential integrity**\n - Enforced by column type\n - Enforced by foreign key constraint\n* - **Complexity**\n - Simple, self-contained\n - Additional table to manage\n* - **Reuse**\n - Must repeat enum definition in each table\n - Single source of truth; multiple tables can reference it\n* - **UI integration**\n - Values must be hardcoded in application\n - Query the table to populate dropdown menus dynamically\n```\n\n```{admonition} When to Use Each Approach\n:class: tip\n\n**Use enums when:**\n- The set of values is small and unlikely to change\n- No additional attributes are associated with each value\n- You want to minimize schema complexity\n\n**Use lookup tables when:**\n- Values need associated attributes (e.g., grade points, descriptions)\n- The set of values may change without requiring schema migration\n- Multiple tables reference the same set of values\n- You need to query or report on the valid values themselves\n- Graphical interfaces or dashboards need to populate dropdown menus—querying a lookup table provides the options dynamically without hardcoding values in the application\n```\n\n```{seealso}\nSee the [Lookup Tables](020-lookup-tables.ipynb) chapter for more details on creating and using lookup tables.\n```",
0 commit comments