Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 如何为带有附件的消息传递系统设置数据库架构?_Sql_Schema - Fatal编程技术网

Sql 如何为带有附件的消息传递系统设置数据库架构?

Sql 如何为带有附件的消息传递系统设置数据库架构?,sql,schema,Sql,Schema,我正在创建一个邮件系统作为一个宠物项目,它将包括有文件附件的功能。这将在我的一个网站上用于内部消息传递系统 这个系统的一个特点是我想维护上传的每个文件的MD5校验和,这样如果上传了重复的文件,两个链接将引用同一个文件 到目前为止,我已经得出了以下结论: Message ---------- MessageID (PK) SenderID (FK) RecipientsID (FK) AttachmentsID (FK) Subject MessageText DateSe

我正在创建一个邮件系统作为一个宠物项目,它将包括有文件附件的功能。这将在我的一个网站上用于内部消息传递系统

这个系统的一个特点是我想维护上传的每个文件的MD5校验和,这样如果上传了重复的文件,两个链接将引用同一个文件

到目前为止,我已经得出了以下结论:

Message
----------
MessageID (PK)  
SenderID (FK)  
RecipientsID (FK)  
AttachmentsID (FK)  
Subject  
MessageText  
DateSent  

Recipient  
----------  
UserID (FK)  
MessageID (FK)  

Attachment  
----------  
ID
Name
MessageID (FK)
FileID (FK)

File  
----------
ID
Checksum
LastAccessDate
AccessCount
因此,您将能够拥有多条消息,每条消息都可以有多个附件。而且,为了节省服务器上的空间,因为我的用例会让用户上传许多相同的文件,不同的附件可以引用相同的文件

我的问题是,消息表是否应该包含某种RecipientsID?或者让我的收件人表引用MessageID就足够了吗

消息表上的AttachmentsID也有相同的问题。我应该有某种附件吗?或者附件表引用MessageID就足够了

如果附件和收件人都知道邮件所属的邮件,则邮件可以不引用其附件或收件人吗?还是我应该用另一种方式

我很想知道一些资深的SQL人员是如何设计这个模式的



编辑:我希望每封邮件有多个收件人和多个附件。如果不清楚的话,我很抱歉


正是在这种一对多的关系中,如果我用最好的方式去做,我很难理解。

您所有的问题都取决于您具体的业务规则。一封邮件可以有多个收件人吗?如果是这样,则无法将收件人ID存储在messages表中,因为这将只允许您为每条邮件存储一个收件人。仔细思考你的每一种情况的逻辑,希望它会变得更清晰

在RDBMS中建立关系模型的标准方法有:

1对多:“多”表中有“1”表的主键。例如,一个订单可以有多个订单行,因此每个订单行都有一个订单id

多对多:两个主表之间存在一个“链接”表,其中包含两个主表的PKs。这些组合的PK通常构成链接表的PK。例如,在大多数情况下,一条消息可以发送给多个用户,并且一个用户可以向他们发送多条消息。在本例中,您有一个多对多关系,因此您将有一个用户表(user\u id、name等)、一个消息表(Message\u id、Message\u body等)和一个Message\u Recipients表(Message\u id、user\u id)

1对1:这类似于从面向对象的角度进行子类化。我的数据库中可能有建筑物,它跟踪某些数据,然后除了这些数据之外,一些建筑物也可能是房屋,它跟踪其他数据。在这种情况下,两个表共享相同的PK


我不打算在这里讨论层次结构,因为它们可以用几种不同的方式建模,而最佳的模型通常取决于系统的特定因素。

您可以将Recipients表放在一起。这是多余的,因为消息表中的RecipientID保存该值。除非你想有不止一个接受者,否则就必须用另一种方式

关于附件,最好是附件表引用消息表,而不是相反。如果消息表有一个附件Id,则将其限制为每条消息只能有一个附件,这可能很好,但如果要将其展开以允许多个附件,则可能会有所限制

另一方面,只有一个附件可以让您将附件ID与消息一起获取,并且您可以连接查询行,以便在一个查询中获取所有附件ID。保存一些代码行

总之,“最低限度”的方法是有一个收件人和一个附件,在这种情况下,您可以将收件人表和messageId放在附件表中。
最广泛的方法是拥有多个收件人和附件,在这种情况下,您可以将recipientId和attachmentId放在邮件表中。

根据您计划存储文件的方式,您需要说明上载的文件名。我知道在Windows上访问文件有一个最大路径长度(其中路径包括完整的文件名和扩展名)。因此,您可能需要为文件指定任意名称,并将实际文件名存储在文件表中。您可能还需要说明上载文件的MIME类型,以便在用户想要查看文档时,您可以通过网站将其提供回来。可以根据扩展名或类似内容阅读并存储,也可以在网站向用户提供文件供下载时查找

Message
---------
msg_id (PK)
sender_id (FK to users_id)
metadata...

Users
---------
user_id (PK)
address (How to locate the user for routing purposes)
metadata....

Attachments
----------
attachment_id (PK)
md5 (possibly UNIQUE, but beware of collisions)
file_sys_ref (a way to find the attachment file in the file system)
meta_data...

Recipients
----------
message_id (FK -> Messages)
user_id (FK -> Users)
meta_data...
PRIMARY KEY (message_id, user_id)

我会将文件存储在文件系统中,而不是作为BLOB存储在数据库中,但这只是我自己。我发现通过外部文件传输机制(ftp、scp、HTTP POST等)传输它更容易,然后编写自己的文件将其分块到数据库中。

这里有很多好的答案,但让我更直接一些:

消息表是否应该包含一些 什么样的接受者

没有

或者我的收信人已经足够了 表引用MessageID

上的AttachmentsID也有同样的问题 消息表。我应该有一个 有什么附件吗

没有

还是说附件已经足够了 表引用了MessageID

没有消息可以吗 对其附件或附件的任何引用 收件人,如果附件和 收件人知道他们收到了哪封邮件 属于


是的。

事实上,facebook也使用类似的方式,详情如下


是的,您可以有多个收件人和多个附件。那些是2