节假日数据规范化

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 系统中。