【问题标题】:Addresses, Times, Days of Week in Database and Domain Objects数据库和域对象中的地址、时间、星期几
【发布时间】:2012-05-30 20:45:28
【问题描述】:

我正在绘制一个非常小的数据库,并且有一些关于良好设计实践的设计问题。假设我有一张 Restaurant 桌子,一家餐厅有一个 Address 和一个 Open Time 和一个 Special Day (MTuWThF)

  1. 餐厅只有一个地址。我很想把所有 相关的地址字段(Street 1、Street 2、City、State、ZIP) Restaurant 表,但我认为将其分解为 自己的表将允许我在我的 域对象,如果我想更改地址的完成方式 以后可能会更容易。我通常认为 1:1 表为 不好的做法...

  2. 营业时间是餐厅营业时间的 HH:MM 表示。我不需要完整的 DateTime 因为 Date 部分会被浪费。那么,varchar 是表示这一点的最佳方式吗?

  3. 还有一个特殊的日子(星期一、星期二等)我也想存储在我的架构中。将这一天存储为 varchar 是否有意义,或者有人会建议使用周日(1)、周一(2)......等创建一个参考表(有点像枚举)。并使用 int 来存储 Special Day 是哪一天?

    **DayOfWeek**
    Id (int)
    Day (varchar)
    
    **Service**
    Id (int)
    RestaurantId (int)
    DayOfWeekId (int)
    ...
    

谢谢大家!

【问题讨论】:

  • 澄清一下,我现在的目标是 MS SQL Server 数据库。

标签: c# sql sql-server database-design


【解决方案1】:

您所问的很多问题都归结为您认为它如何最适合您的需求。希望我在下面说的一些内容会有所帮助。

一对一的表不一定不好,事实上,它们有时用于对数据进行分区以提高检索效率。例如,如果有 10 个您经常使用的字段和另外 25 个相对较大但您不经常使用的字段,您可以将这 25 个放在另一个一对一的表中,这样数据库引擎就不会当您一直在使用 10 个字段时,必须与他们打交道。

在你的情况下,我可以选择任何一种方式。除非您是经验丰富的开发人员,否则我建议您将地址字段放入餐厅餐桌。你不想多想。试图变得太花哨可能只会让你在可能永远不会发生的事情上浪费大量时间和精力。此外,如果您决定稍后更改地址表中的数据,老实说,仅在地址表上运行一些 ALTER TABLE 命令不会比直接在餐厅表上运行它们更容易。简而言之,请保持简单,除非您知道稍后会更改它。

关于时间,一些数据库系统实际上支持 TIME 类型(带有日期)。例如,这里是MySQL's documentation on it。另一种选择是仅使用标准 DATETIME,但以特定日期作为参考点。例如,1970 年 1 月 1 日。因此,如果要存储下午 3:30,请将其存储为“1970-01-01 15:30:00”。您可以在后端执行任何您想要仅显示时间部分的格式。这样做的优点之一是,如果您最终希望在任何类型的计算中使用这些时间,将它们存储为 DATETIME 比存储为 VARCHAR 更容易。例如,如果您想知道某家餐厅在某一天营业了多长时间,您可以使用类似的方法:

SELECT `closetime` - `opentime` AS "openhours" FROM `restaurants`;

至于存储一周中的某一天,老实说,我只是将其设为 TINYINT 并存储 1(星期日)到 7(星期六)。 MySQL 具有返回 1 到 7 作为一周中的一天的内置函数,我认为大多数数据库在这一点上都是相同的。这样可以更容易地在如下查询中确定给定日期是否是“特殊”日子:

SELECT * FROM `restaurants` where DAYOFWEEK(?) = `special_day`

大多数脚本语言都允许您将其编译为准备好的查询,然后您可以非常有效地通过管道输入日期。

希望这对您有所帮助并给您一些考虑。祝你的项目好运,日期和时间处理起来真的很麻烦,尤其是当你开始进入时间跨度之类的时候。

【讨论】:

  • 好主意。我很惊讶没有其他人对这个问题有任何想法。我知道它是主观的并且取决于具体的项目,但它对我来说仍然很令人惊讶。我想我会在 Restaurant 表上捎带地址信息,并在当天使用带有后备表的整数。 SQL Server 支持 TIME 类型,所以我也可能使用它。
【解决方案2】:

我正在绘制一个非常小的数据库

因此很可能您的整个数据库都适合缓存,因此几乎没有理由为了更好的 I/O 而垂直拆分表 - 没有 I/O 可言。

1...

数据库应该关心数据,而不是它在客户端应用程序代码中的表示方式。我相信您将能够在代码中以可接受的方式使用地址,即使它不在单独的表格中。至少,您始终可以手动包装 ORM 生成的任何内容(或者首先不使用 ORM ;))。

2...

嗯,一天有 24 * 60 = 1440 分钟,这在smallint 中很合适。

如果您只想查询小时(或分钟),请将它们分开放在两个 tinyint 字段中。

3...

使用单独的表和参照完整性。这样,您可以在一个地方更改哪一天是特殊的,它会自动“传播”到所有连接的行。如果需要,您可以有多个特殊的日子。

OTOH,如果您知道您总是有一个特殊的日子,那么您可以创建一个“单例”表,其中一行仅包含那一天。在这种情况下,您实际上不需要任何 FK - 由于天数很少 (7),因此仅通过 CHECK 约束来限制有效值是可行的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-08-19
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    相关资源
    最近更新 更多