数据库和域对象中的地址、时间、星期几
本文关键字:时间 地址 对象 数据库 | 更新日期: 2023-09-27 18:35:45
我正在绘制一个非常小的数据库,并有一些关于良好设计实践的设计问题。假设我有一个餐厅的桌子,一家餐厅有一个地址和一个营业时间和一个特殊的日子(MTuWThF)
-
一家餐厅只有一个地址。我很想把所有关联的地址字段(街道 1、街道 2、城市、州、邮政编码)进入餐厅的桌子,但我认为将其分解成自己的表将允许我在我域对象,如果我想更改地址的完成方式稍后可能会使它更容易。我通常认为 1:1 桌子是不好的做法...
营业时间 是餐厅营业时间的 HH:MM 表示形式。我不需要完整的日期时间,因为日期部分会被浪费。那么,瓦尔查尔是最好的表现方式吗?
有一个特殊的日子(星期一,星期二等)我也想存储在我的架构中。将这一天存储为 varchar 是否有意义,或者有人会建议使用星期日 (1)、星期一 (2) 创建一个参考表(有点像枚举)......等等,并使用 int 来存储特殊日子的哪一天?
**DayOfWeek** Id (int) Day (varchar) **Service** Id (int) RestaurantId (int) DayOfWeekId (int) ...
谢谢大家!
你问的很多问题都归结为你认为它如何最适合你的需求。 希望我在下面说的一些内容会有用。
一对一表不一定是坏表,事实上,它们有时用于对数据进行分区以提高检索效率。 例如,如果有 10 个字段经常使用,还有 25 个字段相对较大,使用次数不多,则可以将这 25 个字段放在另一个一对一表中,这样数据库引擎就不必在抓取您一直使用的 10 个字段时对它们进行摸索。
在你的情况下,我可以走任何一条路。 除非您是经验丰富的开发人员,否则我建议将地址字段放入餐厅餐桌中。 你不想想太多。 试图变得太花哨可能只会导致你在可能永远不会发生的事情上浪费大量的时间和精力。 此外,如果您决定稍后更改地址表中的数据,老实说,在地址表上运行一些 ALTER TABLE 命令与直接在餐厅餐桌上运行它们相比,在地址表上运行它们并不容易。 简而言之,保持简单,除非您知道以后要更改它。
关于时间,一些数据库系统实际上支持TIME类型(带有日期)。 例如,这是MySQL的文档。 另一种选择是仅使用标准 DATETIME,但使用特定日期作为参考点。 例如,1970 年 1 月 1 日。 因此,如果要存储下午 3:30,请将其存储为"1970-01-01 15:30:00"。 您可以在后端执行任何要仅显示时间部分的格式设置。 这样做的一个优点是,如果你想最终在任何类型的计算中使用这些时间,将它们存储为 DATETIME 比存储为 VARCAR 要容易得多。 例如,如果您想知道餐厅在特定日期的营业时间,则可以使用以下内容:
SELECT `closetime` - `opentime` AS "openhours" FROM `restaurants`;
至于存储一周中的一天,老实说,我只是把它做成 TINYINT 并存储 1(星期日)到 7(星期六)。 MySQL 具有内置函数,每周返回 1 到 7 作为一天,我认为大多数数据库都是一样的。 这将使在以下查询中更容易确定给定日期是否为"特殊"日期:
SELECT * FROM `restaurants` where DAYOFWEEK(?) = `special_day`
大多数脚本语言都允许您将其编译为准备好的查询,然后您可以非常有效地管道日期。
希望这有所帮助,并为您提供一些注意事项。 祝你的项目好运,日期和时间可能会变得非常棘手,尤其是当你开始进入时间跨度等时。
因此,我正在绘制一个非常小的数据库
您的整个数据库很可能适合缓存,因此几乎没有理由为了更好的 I/O 而垂直拆分表——没有 I/O 可言。
1...
数据库应该关心数据,而不是数据在客户端应用程序代码中的表示方式。我相信您将能够在代码中以可接受的方式使用地址,即使它不在单独的表中。至少,您始终可以手动包装ORM生成的任何内容(或者首先不使用ORM;))。
阿拉伯数字。。。
好吧,一天有 24 * 60 = 1440 分钟,这将舒适地适合smallint
.
如果只想按小时(或仅分钟)进行查询,请在两个tinyint
字段中将它们分开。
3...
使用单独的表和参照完整性。这样,您可以在一个地方更改哪一天是特殊的,它将自动"传播"到所有连接的行。如果需要,您可以有多个特殊的日子。
OTOH,如果你知道你总是有一个特殊的日子,那么你可以创建一个"单例"表,其中一行只包含那一天。在这种情况下,您实际上不需要任何 FK - 由于天数很少 (7),因此仅通过 CHECK 约束来限制有效值在实用范围内。