Jas*_*son 5 database-design sql-server table
我正在尝试设计数据库表来跟踪最终用户上传的文件。
文件可以在不同的上下文中上传。
每个上下文都是一个不同的表。
举个例子:
这个(人为的)场景中的实体/表是:
Employees (Id, Name)
Expenses (Id, Date, RequestedRefund, RequestedByEmployeeId)
Pets (Id, Name, Type, BelongsToEmployeeId)
我已经有一个名为的表Files
,用于跟踪有关文件本身的信息:
Files (Id, Name, Size, Extension, Folder)
我的问题是关于如何根据文件记录映射费用收据上传和宠物照片上传。我知道我可以通过两种方式做到这一点:
有一个通用映射表:GenericFileMap (FileId, ContextId, Type)
where
FileId
是文件记录的id ContextId
是我试图检索的上下文记录的 ID Type
是描述上下文本身的字段 在这种情况下,我会像这样获取员工的所有费用收据:
SELECT *
FROM Employee e
INNER JOIN Expenses ex ON e.Id = ex.RequestedByEmployeeId
INNER JOIN GenericFileMap g ON g.ContextId = ex.Id AND g.Type = 'expense'
INNER JOIN Files f ON g.FileId = f.Id
Run Code Online (Sandbox Code Playgroud)
每个实体/上下文表都有单独的映射表:
ExpenseFiles (ExpenseId, FileId)
PetFiles (PetId, FileId)
收据查询将是:
SELECT *
FROM Employee e
INNER JOIN Expenses ex ON e.Id = ex.RequestedByEmployeeId
INNER JOIN ExpenseFiles ef ON ef.ExpenseId = ex.Id
INNER JOIN Files f ON ef.FileId = f.Id
Run Code Online (Sandbox Code Playgroud)
我相信第一个选项不是在关系数据库中做事的“规范化”方式。但我考虑这一点的唯一原因是,在我的特定情况下,用户可以上传/附加文件至少有 15 种不同的上下文。
我从第一个选项中看到的唯一好处是我为每个上下文节省了创建和复制表和存储过程(每个用于 CRUD)的时间。
然而,似乎第二种选择是做事的“正确”方式。
我的问题:
您不需要选项#1,因为:
ContextId
和Type
放入桌子中Files
。TypeID TINYINT
字段(以及关联的Type
查找表),这样您就不需要每次都进行低效的字符串比较。最好的可能是修改选项#2。是的,从特定于上下文的文件映射表(例如,,等)开始,ExpenseFiles
但PetFiles
也要ContextTypeID TINYINT
在现有Files
表中添加一列。还应该有一个新的ContextType
查找表ContextTypeID TINYINT NOT NULL
作为主键(但不要将其设为IDENTITY
列)。您可以Name
向查找表添加一列,并添加一个外键 fromFiles
到ContextType
on ContextTypeID
。在表中添加这个新列Files
将使您更容易确定关联记录位于哪个上下文特定的文件映射/属性表中。
即使存在 15 种不同的环境,选择选项 2 的原因是,不可避免地,至少其中一些会随着时间的推移而演变和分歧。所以你可能有:
ExpenseFiles (ExpenseId, FileId, Date, Total)
PetFiles (PetId, FileId, Name, Age, AnimalType)
归档时间: |
|
查看次数: |
2309 次 |
最近记录: |