我正在重新设计一个旧的数据库,该数据库从小开始,现在由于多年来发生系统更改时的快速修复而变得非常臃肿和缓慢。 无论这次设计得多好,当然会有不可预见的变化,所以我正在寻找一些关于如何最好地准备这些变化的一般性提示,以及关于我是否在正确轨道上的一般建议。 我对软件开发/数据库设计世界很陌生,所以请原谅我,如果这里有一些明显的问题,或者我有点过于模糊......我正在尽我所能:)
具体而言;
将在网站上进行预订。在预订时,可能会添加一些额外费用/要求,例如:预订停车位 - 用户将指示是否需要停车位。 我将创建另一个'DisabledSpacesRequired'表,它将有一列 - 需要禁用空间的那些的预订ID。这比在预订表中有一个标志表明是否需要这个空间更“好”吗?
同样,预订可能会被取消 - 因此会有一张已取消预订的表格。为了以后搜索,最好只是在取消预订表中搜索bookingID?或者在预订表中有一个标志,表明它是否被取消了? (无论如何,'CancelledBookings'表是必要的,但是还应该包括一个标志吗?)
让我想到这些问题的原因是数据库中目前似乎有很多附加组件 - 例如有一个“订阅者”表,并且后面添加了一个“SubscribersTwitterHandles”表 - 以这种方式分离出订阅者类型是一种好习惯吗?或者在现有表中添加标志?
我已经看过一些类似的问题了 Implementing Review flags in Databases; best practices 我认为最好将变量分开以准备将来可能进行的更改。 (例如,我们可能希望添加一些与所需的残疾停车位相关的信息。)
希望我很清楚 - 非常感谢任何建议。
答案 0 :(得分:0)
我试图从数据库设计的角度分享我的观点,
这些是非常基本的数据库设计技术,但人们有时也会进行权衡,而不是这样做以便于编码/查询。但我认为这可能是一个不同的故事。
答案 1 :(得分:0)
关于数据库中的标志有很多意见。所以常见的答案是“好吧,这取决于你想要你的RBDMS做什么”。
我每天工作的学生信息系统在基础学生表中有一个状态标志。法律价值观是A - 主动,I - 非主动,P - 预先注册,G - 毕业。没有验证表或查找表。它在应用程序中是硬编码的。虽然这是一个问题,但应用程序运行完美。学生总是拥有一个且只有一个状态,并且现有状态列表不会覆盖任何情况。您可以添加regtb_status
查找表并向学生注册表添加外键约束,但它不会对此应用程序增加太多。
对于您的预订示例,我将在Booking表中拥有当前状态字段。我更喜欢使用字符字段,因此我可以支持我知道可能需要的状态:A - 活动,C - 由客户取消,I - 无效,D - 由工作人员删除等。您甚至可以允许客户可以访问验证表,以便他们可以根据需要创建自定义状态。这取决于您想象的工作流程以及您的客户想要的工作流程。
在同一系统的其他地方,有很多状态标志字段是硬编码的CHAR(1)
字段,它们是Y - 是和N - 否。你可能应该使用你的RDBMS的布尔类型来表示这些标志,但是除非你谈论荒谬的记录或者需要担心国际化,否则它不会成为一个问题。这些类型的表通常也用作联结表。例如,将学生与联系人联系起来的表包括联系人是否与学生一起生活的状态标志,联系人的类型(监护人,紧急联系人),联系人与学生的关系(母亲,父亲,阿姨等) 。),该联系人是否应该可以访问母网站中的学生,联系人的优先顺序,父母是否应该通过邮件接收报告卡等。这个特殊的表格有点麻烦,因为有此表中的十几个标志字段,但多个标志选项关系类型在应用程序内的验证/查找表中是完全可配置的,并且列名称至少部分是自我记录。从报告撰写的角度来看,这是非常宝贵的。
我们有几个字段存储在用户定义的表中,这些字段实际上将所有内容存储在DB中的EAV表中。这会导致问题,因为通常情况下,特定的EAV记录在学校明确设置之前不存在。该应用程序的行为就像null = No,但它可以使编写报告甚至在应用程序中搜索变得困难。你无法找到field = 'N'
。你必须寻找field = 'N' OR field IS NULL
。在应用程序的搜索系统中,您必须指定field <> 'Y'
,因为它在所有情况下都不能很好地处理空值。这对于那些无法围绕三个有价值逻辑的用户来说非常困惑。这对DBA来说也是相当恼人的,因为查看数据的最佳方式是一个视图,不容易更新。
根据我的经验,位掩码几乎总是不正确。查询它们非常繁琐且昂贵,而不是自我记录,并且通常是尾部的巨大痛苦。我希望看到一系列BIT
/ BOOLEAN
或CHAR
字段,而不是位掩码。如果它在一个字段中有多个属性,那将是一个巨大的问题。
对于您的SubscribersTwitterHandles问题,我想我有点困惑。为什么他们只是在现有表中添加一列?它是一对多关系,还是有多个Twitter句柄字段?要么你的客户没有给你他们的处理 - 在这种情况下它是明确的''
- 或者它是他们给你的句柄。
我想从设计的角度来看我真正的问题:我们是在创建标志还是标签?在我看来,标志与数据库中的现有实体具有一对一的关系。该实体可能是两个实体之间的联结,也可能是实体本身,但它总是具有非空值。
另一方面,标签是任意的,可能是多对一或多对多,在大多数情况下,客户完全将其定义为对记录进行分组的临时方法。
答案 2 :(得分:-1)
取决于:)
您必须了解数据的使用方式。如果有数万亿个表用于标记,则查询将包含许多连接以检索所有信息。
如果您不想在这些列中搜索,那么它可能是一个标志列(或者是包含多个列的所有标志的单独表)。您可以在某些RDBMS中存储多个标志(例如,MySQL&#39; enum&#39;以及&#39;设置&#39;类型)。您还可以将标志存储在位掩码中(整数)。
如果要搜索这些标志(并且标志是主过滤器),单独的表可能有所帮助。只需加入这些表就可以了,但是有了多个搜索标准,就很难实现。 (想象一下,当您要搜索所有需要停车场标志或禁用插槽的记录时)
您还可以将它们存储在键值对中。 (bookingId,flagType),当有要设置的自定义标志时,这很有用。
再一次:了解您的数据并了解您的RDBMS如何工作。您必须考虑要优化存储空间或其他资源(CPU使用,内存,磁盘IO等)。总会有利有弊。当您无法确定哪种实施方案最佳时,请设置一些测试用例并测量最重要的指标以获取更多信息。
编辑:在您的具体情况下,我认为,这些标志不会充当过滤器,因此您可以将它们存储在一列中(每个列分别存储一个或以位掩码分组)。