您将针对此特定数据库设计问题使用哪种方法?

时间:2010-02-09 14:34:04

标签: sql sql-server database

仅针对以下两种情况寻找意见。

我们有一个表格,用于存储我们的出站短信。每当我们的某个服务发送一个优惠费率消息时,它就会将它们存储在此表中......到目前为止,所有需要存储的重要信息都采用相同的格式。

SMSMessages
----------------------
ID              int PK NOT NULL Identity
Mobile          nvarchar(50) -- the number we're sending to
NetworkID       int FK -> Table containing networks (voda, o2, etc...)
ShortcodeID     int FK -> Table containing our outbound shortcodes
DateSent        DateTime

现在其中一个网络实现了一个我们需要集成的全新API,需要更多参数。这些附加参数中的一个是“命令”。根据我们发送的命令,我们需要发送4到8个附加参数。为了简单起见,我们会说只有两个命令......“InitialSend”& “AnniversarySend”

显然,只需将所有这些额外的列添加到现有表格的末尾就是非常糟糕的数据库设计,所以...我们认为我们有两个选项。

选项1。

创建许多特定于每个命令的新表,链接回 原始表。

SMSMessages_CommandTypes --Contains "InitialSend" & "AnniversarySend" + other commands
--------------------------
CommandTypeID   int PK
Command     nvarchar(50)


SMSMessages_OddBallNetwork
--------------------------
ID              int PK, FK --> SMSMessages.ID
CommandTypeID   int FK ---> SMSMessages_CommandTypes


SMSMessages_OddBallNetwork_InitialSend
--------------------------------------
ID              int PK, FK --> SMSMessages.ID
Param1          nvarchar(50)
Param6          nvarchar(50)
Param9          nvarchar(50)
Param14          nvarchar(50)

SMSMessages_OddBallNetwork_AnniversarySend
--------------------------------------
ID              int PK, FK --> SMSMessages.ID
Param1          nvarchar(50)
Param2          nvarchar(50)
Param7          nvarchar(50)
Param9          nvarchar(50)
Param12          nvarchar(50)

//There are 4 other Command Types as well so 4 More Tables...

根据我们的DBA,这个人的专业人士都是纯粹的。每种可能的组合都是明确定义的关系很清晰,表现最好。

从我的POV中,缺点是开发时间,触摸点数量,具有不同命令类型的消息的复杂检索规则/过程,以及缺乏可重用性......此移动网络或其他网络上的新命令引入此方法需要DB级别设计和实现......而不仅仅是代码级​​别。

选项2。

此选项是尝试使用更少,更可重用的结构设计一个动态实现。

SMSMessages_AdditionalParameterTypes
------------------------------------
ParamterTypeID  int PK NOT NULL Identity
ParamterType    nvarchar(50)

/*
This table will contain all known parameters for any messages
CommandName
Param1
Param2
etc..
*/

SMSMessages_AdditionalParameters
--------------------------------
ID              int PK NOT NULL Identity
MessageID       int FK --> SMS Messages
ParamTypeID     int FK --> SMSMessages_AdditionalParameterTypes
Value           nvarchar(255)

这方面的利弊。

缺点: 关于params与哪些消息相关联,你的可见性不太明显 还有一个小的性能问题... N 插入每条消息而不仅仅是2

优点: 对(imho)开发来说,这是一个很容易的地狱。您只需获取参数名称列表 - >返回给定messageID的值

它还有更多可重复使用...如果奇怪的网络添加新命令,命令上的新参数,或者即使另一个网络出现并实现类似的“我想要更多信息”API,我们也不需要我们系统的任何结构变化。

所以...你会做什么?

6 个答案:

答案 0 :(得分:3)

为什么

为什么需要存储此信息?报道了吗?搜索?用于摘要和分类分析?实时?经常?

少做

如果此数据仅用于记录,请将其粘贴到文本或xml字段中并忘记它。 YAGNI(你不需要它)似乎很可能......

严重

在不知道数据用途的情况下,没有人可以回答这个问题,包括你。

是的,一个完全规范化的逻辑数据库结构很棒并且提供了清晰度等等。但是它有用吗?

并非所有数据都是黄金;有些只是CYA

答案 1 :(得分:2)

选项2为我赢了。对于性能问题,你应该只为oddball网络提供额外的插入,而且无论如何都会出现问题。对于可见性问题,我认为这是一个感知问题。在使用新系统一段时间后,查看消息参数要求可能会成为第二天性。

答案 2 :(得分:2)

这听起来像数据记录情况,只需要对CYA目的而言“足够好”。完全标准化的模型是正确的,但对于你将要做的事情来说似乎有点过分。如果您只是需要一些预制查询,以便某些审核员访问,那么这些查询可能不需要亚秒响应时间。

我相应地推荐了之前的条目。

答案 3 :(得分:1)

我会创建以下表格

SMSMessages
SMSMessages_AdditionalParameterTypes(ParamterTypeID, ParamterType, Operator)
SMSMessages_Parameters(MessageID,ParamTypeID,Value)

答案 4 :(得分:1)

  

显然它会非常可怕   数据库设计只需添加所有这些   我们最后的附加列   现有表格

不要认为这是一个可怕的设计:它肯定会让你的代码尽可能简单。使用good name作为列,而不是“param1”或类似的内容。

commandtype的外键关系是一个好主意(基本上是枚举的SQL等价物。)

将通常为列的列放在不同的表中(又名“动态列”)会增加很多复杂性。实际上,除非您打算允许最终用户添加动态列,否则这几乎永远不值得。

最重要的是,一旦你完成了设计,就可以为常见任务编写几个示例查询。这通常有助于澄清哪种复杂性实际上是值得的。

答案 5 :(得分:1)

个人选项2让我不寒而栗,因为我确信它会对你的dbas产生影响。如果需要查询数据,实体值表是存储数据的最差方式。这通常不是您想象的“小”性能,但“大”性能会影响您的dbas设想。 DBA总是陷入困境,无法修复人们以这种方式设计的性能较差的系统,因为它看起来更面向对象并且可以理解。这就是为什么当人们提出这些类型的设计时我们讨厌它。

为方便程序员而设计数据库存储是短视和不专业的。数据库必须旨在实现完整性,性能和安全性。对抗它的时间是一个遥远的,遥远的第四个。数据库不像应用程序代码那样容易重构,您可能会在接下来的二十年中坚持使用这种设计。

现在真正的问题是你需要查询这些数据(除了根据其他标准返回查询中的值)吗?如果您不需要很少查询或查询,那么只需将所有额外数据放入varchar(max)字段并完成它。