节假日数据规范化
Data Normalisation on Holiday
我们正在开发一个系统,使用 MySQL 数据库涉及假期。
有些假期可能只适用于某些州,例如:耶稣受难日仅适用于夏威夷、肯塔基、路易斯安那等
holiday | state
---------------------
Good Friday | Connecticut, Delaware, Hawaii, Indiana, Kentucky, Louisiana, New Jersey, North Carolina, North Dakota, Tennessee
我们的团队讨论了规范化后状态应该如何存储在MySql数据库中。
首先我们得出如下设计(跳过一些列,如日期或假期id):
设计 A
holiday | state code
------------------------
Good Friday | CT
Good Friday | DE
Good Friday | HI
Good Friday | IN
Good Friday | KY
Good Friday | LA
Good Friday | NJ
Good Friday | NC
Good Friday | ND
Good Friday | TN
但是我们的一位团队成员提出了另一种设计:
设计 B
holiday | state
---------------------
Good Friday | CT,DE,HI,IN,KY,LA,NJ,NC,ND,TN
设计B 看起来和我所学的数据库设计规范化有矛盾,但我的团队成员坚持这是正确的方法,从未见过有人设计table 喜欢 设计 A
请问哪一个更合适?或者在数据库设计中是否有一些我不知道的新方法导致设计B被用于当前的数据库设计?
谢谢
[编辑]
为了使事情更具体,假期 table 的目的是计算截止日期:
date_begin + N working days = due_date
如果 N = 3 并且日期开始是 2020-04-07,(假设星期六是工作日)
2020-04-07 + 3 = 2020-04-10 // Good Friday
如果案例登记在 康涅狄格州,其中 2020-04-10 是假期,因此截止日期将为 2020-04-11,但如果案件在其他州注册,例如华盛顿特区,截止日期将为 2020-04-10.
典型的设计如下:
Holidays
---------
ID | Name | ....
--------------------------
1 |Good Friday |...
2 |Easter Monday|...
3 |Christmas Day|...
...
States
----------
ID | Name
---------------------------
1 | Connecticut
2 | Texas
3 | Vermont
....
State_Holiday
----------------
State_ID | Holiday_ID
----------------------
1 | 1
2 | 1
3 | 2
.....
通过使用 table 定义存在哪些假期,并通过外键 (holiday_id) 引用它们,您可以避免拼写错误 - 在设计 A 中,有人可能会输入“good friday” (不是大写),你的应用程序会不清楚它是否与“Good Friday”相同。
州同上 - 州缩写代码可能足以作为主键,但我不确定它们是否保证唯一(是否有其他国家/地区使用这些代码?)
加入 table State_Holiday 可以很容易地找到给定的州有哪些节假日,或者哪些州有给定的节假日。
[编辑]
现在您已经概述了示例用例,想象一下使用设计 B 执行它。
您必须进行一大堆字符串解析才能确定康涅狄格州是否在 date_begin 和 date_begin + N 之间的某一天放假。您必须处理分隔符,以及您无法在数据模型级别保证状态代码为 2 个字符的事实。比较运算符几乎肯定是类似于 and state like '*CT*'
的东西,因为索引不起作用,它的性能会非常糟糕。您需要应用程序级逻辑来确保状态代码正确 - 您不能在数据模型中强制执行参照完整性。
选项 A 简单得多 - 您只是比较一堆外键,而不是进行字符串比较。您的参照完整性由数据模型而非应用程序逻辑强制执行。
习惯于使用关系数据库的人更喜欢选项 A;它已标准化,使用参照完整性并且应该表现良好,无论您有多少假期。
选项 B 是一种“NoSQL”方法。这是完全不同的对话,但我不会将 NoSQL 设计强加到 MySQL 系统中。
我们正在开发一个系统,使用 MySQL 数据库涉及假期。
有些假期可能只适用于某些州,例如:耶稣受难日仅适用于夏威夷、肯塔基、路易斯安那等
holiday | state
---------------------
Good Friday | Connecticut, Delaware, Hawaii, Indiana, Kentucky, Louisiana, New Jersey, North Carolina, North Dakota, Tennessee
我们的团队讨论了规范化后状态应该如何存储在MySql数据库中。
首先我们得出如下设计(跳过一些列,如日期或假期id):
设计 A
holiday | state code
------------------------
Good Friday | CT
Good Friday | DE
Good Friday | HI
Good Friday | IN
Good Friday | KY
Good Friday | LA
Good Friday | NJ
Good Friday | NC
Good Friday | ND
Good Friday | TN
但是我们的一位团队成员提出了另一种设计:
设计 B
holiday | state
---------------------
Good Friday | CT,DE,HI,IN,KY,LA,NJ,NC,ND,TN
设计B 看起来和我所学的数据库设计规范化有矛盾,但我的团队成员坚持这是正确的方法,从未见过有人设计table 喜欢 设计 A
请问哪一个更合适?或者在数据库设计中是否有一些我不知道的新方法导致设计B被用于当前的数据库设计?
谢谢
[编辑]
为了使事情更具体,假期 table 的目的是计算截止日期:
date_begin + N working days = due_date
如果 N = 3 并且日期开始是 2020-04-07,(假设星期六是工作日)
2020-04-07 + 3 = 2020-04-10 // Good Friday
如果案例登记在 康涅狄格州,其中 2020-04-10 是假期,因此截止日期将为 2020-04-11,但如果案件在其他州注册,例如华盛顿特区,截止日期将为 2020-04-10.
典型的设计如下:
Holidays
---------
ID | Name | ....
--------------------------
1 |Good Friday |...
2 |Easter Monday|...
3 |Christmas Day|...
...
States
----------
ID | Name
---------------------------
1 | Connecticut
2 | Texas
3 | Vermont
....
State_Holiday
----------------
State_ID | Holiday_ID
----------------------
1 | 1
2 | 1
3 | 2
.....
通过使用 table 定义存在哪些假期,并通过外键 (holiday_id) 引用它们,您可以避免拼写错误 - 在设计 A 中,有人可能会输入“good friday” (不是大写),你的应用程序会不清楚它是否与“Good Friday”相同。
州同上 - 州缩写代码可能足以作为主键,但我不确定它们是否保证唯一(是否有其他国家/地区使用这些代码?)
加入 table State_Holiday 可以很容易地找到给定的州有哪些节假日,或者哪些州有给定的节假日。
[编辑] 现在您已经概述了示例用例,想象一下使用设计 B 执行它。
您必须进行一大堆字符串解析才能确定康涅狄格州是否在 date_begin 和 date_begin + N 之间的某一天放假。您必须处理分隔符,以及您无法在数据模型级别保证状态代码为 2 个字符的事实。比较运算符几乎肯定是类似于 and state like '*CT*'
的东西,因为索引不起作用,它的性能会非常糟糕。您需要应用程序级逻辑来确保状态代码正确 - 您不能在数据模型中强制执行参照完整性。
选项 A 简单得多 - 您只是比较一堆外键,而不是进行字符串比较。您的参照完整性由数据模型而非应用程序逻辑强制执行。
习惯于使用关系数据库的人更喜欢选项 A;它已标准化,使用参照完整性并且应该表现良好,无论您有多少假期。
选项 B 是一种“NoSQL”方法。这是完全不同的对话,但我不会将 NoSQL 设计强加到 MySQL 系统中。