数据库和域对象中的地址,时间,星期几

时间:2012-05-30 02:37:57

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

我正在绘制一个非常小的数据库,并且有一些关于良好设计实践的设计问题。假设我有一个餐厅表,一家餐馆有一个地址和一个开放时间和一个特殊日子 (MTuWThF)

  1. 餐厅只有一个地址。我很想放一切 相关的地址字段(街道1,街道2,城市,州,ZIP) 进入餐厅表,但我想把它分解成它 自己的表将允许我在我的内部创建一个地址类 域对象,如果我想改变地址完成的方式 以后它可能会更容易。我通常认为1:1表为 不好的做法...

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

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

    **DayOfWeek**
    Id (int)
    Day (varchar)
    
    **Service**
    Id (int)
    RestaurantId (int)
    DayOfWeekId (int)
    ...
    
  4. 谢谢你们!

2 个答案:

答案 0 :(得分:0)

您要问的很多内容归结为您认为它最适合您的需求。希望我在下面说的一些内容会很有用。

一对一表不一定是坏的,事实上,它们有时用于分区数据以提高检索效率。例如,如果有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`

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

希望这会有所帮助,并为您提供一些注意事项。祝你的项目顺利,日期和时间真的很难处理,尤其是当你开始进入时间跨度等时。

答案 1 :(得分:0)

  

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

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

  

1 ...

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

  

2 ...

嗯,一天有24 * 60 = 1440分钟,适合smallint

如果您只想查询小时数(或仅分钟数),请将它们分成两个tinyint字段。

  

3 ...

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

OTOH,如果你知道你将总是只有一个特殊的日子,那么你可以创建一个“单身”表,其中一行只包含那一天。在这种情况下,您不需要任何FK - 因为天数很小(7),仅通过CHECK约束限制有效值在实用范围内。