衍生概念——数据库设计注意事项
我有一个主要概念 - 邮件消息和两个派生概念:
- 模板生成的电子邮件
- 自由格式电子邮件
我正在考虑创建三个表来保存数据,我需要您对此事的意见(如果是的话)不好,如果好的话,如何改进等等):
MailMessages
- Id [int] identity(自动增量) PK
- ToAddress [varchar(300)]
- IsTemplateBased [bit ]
- TemplateId [int] 可为 null FK
- MailBodyId [int] 可为 null FK (TemplateId 必须为 null 并且MailBodyId 必须为非空,反之亦然)
- StatusId [tinyint] FK
MailParams
- MailMessageId [int] PFK
- ParamNumber [tinyint]
- 值 [nvarchar(4000) ]
MailBody
- MailMessageId [int] PFK
- FromUsername [varchar(30)]
- FromDomainId [tinyint] FK
- PlainTextContent [nvarchar(max)]
- HtmlContent [nvarchar(max)] nullable
这里有一些解释:
- 我希望设计尽可能规范化
- IsTemplateBased 位(布尔)列可以省略,邮件消息的性质可以从 TemplateId 和/或 MailBodyId 推断出来(即:如果 TemplateId 不为空,那么它是基于模板的),但我认为这种反规范化(?)可能对性能有用
- 拥有两列(FromUsername 和 FromDomainId)背后的原因是强制执行电子邮件健全性规则 - 我不认为拥有单个列(FromAddress)是合适的
说了所有这些,亲爱的读者,您的意见是什么?
I have a main concept - Mail message and two derived concepts :
- template-generated emails
- free-form emails
I am thinking of creating three tables to hold the data and I need your opinions on this matter (if it's bad, if it's good, how can it be improved and so on) :
MailMessages
- Id [int] identity (autoincrement) PK
- ToAddress [varchar(300)]
- IsTemplateBased [bit]
- TemplateId [int] nullable FK
- MailBodyId [int] nullable FK (TemplateId must be null and MailBodyId must be non-null or vice-versa)
- StatusId [tinyint] FK
MailParams
- MailMessageId [int] PFK
- ParamNumber [tinyint]
- Value [nvarchar(4000)]
MailBody
- MailMessageId [int] PFK
- FromUsername [varchar(30)]
- FromDomainId [tinyint] FK
- PlainTextContent [nvarchar(max)]
- HtmlContent [nvarchar(max)] nullable
A few explanations are in order here :
- I would like a design as normalized as possible
- The IsTemplateBased bit (boolean) column can be omitted and the nature of the mail message can be inferred from TemplateId and/or MailBodyId (i.e.: if TemplateId is not null then it's template-based) but I think this de-normalization (?) could be useful for performance
- The reason behind having two columns (FromUsername and FromDomainId) is to enforce email sanity rules - I don't consider having a single column (FromAddress) as being appropiate
Having said all these, what are your opinions, dear readers?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是上面 @Philip Kelley 指出的“标准类型/子类型”模型的示例:
你已经得到
SupertypeType。约束类型标识符的域的域表。
超类型。常见的超类型。对于子类型实例之一的每个实例,此表中都存在一行。它包含对象 ID (SupertypeID)、对象类型标识符 (TypeID) 以及所有子类型通用的属性。
子类型。每个子类型都存在一个表。它的主键是超类型表的对象 ID。对于超类型的每个实例,所有子类型表中不存在超过一行(当然,如果所讨论的实例属于基(超)类型,则可能没有行。每个子类型表各不相同,包含属性对于该特定子类型是唯一的。
要枚举所有元素,请查询仅超类型表。
如果您知道您只对特定子类型感兴趣,则只需从适当的子类型表中进行选择,根据需要连接超类型表即可获取所需的任何公共属性。
< /strong> 如果您需要整个集合的平面、非规范化视图,只需在子类型之间进行左连接:
现在您不需要多个查询。你用它来换取必须处理无效性。
Here's an example of the "standard type/subtype" model noted by @Philip Kelley above:
You've got
SupertypeType. The domain table that constrains the domain of the type identifier.
Supertype. The common supertype. A row exists in this table for every instance of one of the subtype instances. It contains the object id (SupertypeID), the object type identifier (TypeID), and the attributes common across all subtypes.
Subtype. A table exists for each subtype. Its primary key is the object id of the supertype table. For each instance of the supertype, no more than one row exists across all the subtype tables (there may be no rows, of course, if the instance in question is of the base (super) type. Each subtype table varies, containing the attributes unique to that particular subtype.
To enumerate all elements, query only the supertype table.
If you know that you're only interesting in a particular subtype, you may simply select from the appropriate subtype table, joining against the supertype table as needed to get whatever common attributes you need.
Addendum. If you need a flat, denormalized view of the entire set, simply left join across the subtypes:
Now you don't need multiple queries. You've traded that for having to deal with nullity.
您可以简化并使其更像标准类型/子类型模型,如下所示:
现在您只有一个,而不是三个不同的代理键(相应地,出现错误和混乱的可能性更大)来管理。
You can simplify and make it a bit more like the standard type/subtype model like so:
Instead of three different surrogate keys (and correspondingly greater chance for error and confusion), you now have only one to manage.
您需要子类型模型,并且还应该考虑消除这些空值所需的任何进一步分解。允许空值的表不是范式。
You need the subtype model and you should also consider any further decompositions you need to eliminate those nulls. A table that permits nulls is not in Normal Form.