sdd*_*dds 1 sql orm database-design relational-database dapper
假设我有一组“模型”实体和一组难度级别。在给定的难度级别下,每个模型在给定的一天中具有一定的成功率。
模型实体具有一个名称,该名称在任何情况下都是唯一且不可变的,因此它成为自然的主键。难度级别仅通过名称来描述(容易,正常等)。难度级别非常非常不可能改变,尽管有可能添加一个新的难度级别。成功率记录由其所属的模型,难度级别和日期唯一标识。
这是此方案中最简单的数据库设计:

在此设计中,“名称”是表“模型”的主键,并由VARCHAR(20)字段表示。同样,VARCHAR(20)字段“名称”是表“ difficulty_levels”(查找表)的主键。在“ success_rates”表中,“ model_name”是引用“ model”表中“ name”字段的外键,而“ difficulty_level”是引用“ difficulty_levels”表中“ name”字段的外键。字段“ model_name”,“ difficulty_level”和“ date”构成“ success_rates”表的复合主键。
最常用的查询是:
获取特定模型,难度级别和日期期限的所有成功率
在特定时期和难度级别获得最多/最少成功的模型。
现在,我的问题是-我需要向“模型”和“ difficulty_levels”表中添加代理主键吗?我猜想在'success_rates'的外键字段中存储int值而不是varchar值会占用较少的空间,并且查询可能会更快(只是我的疯狂猜测,不确定这一点)?
我使用代理键看到的问题是它们与业务逻辑本身的相关性为零。我正在计划使用一个迷你ORM(很可能是Dapper),并且没有代理键,我就可以在非常干净地代表我正在使用的实体的类上进行操作。现在,如果添加代理键,则必须在类中添加“ Id”属性,而我真的反对将这样的数据库存储实现添加到可在应用程序中任何位置使用的类,甚至不能在与数据库存储的连接。我可以使用Id属性添加代理存储类,但这又增加了另一层次的复杂性。加上“ Id”属性不是只读的事实(因此,ORM在将实体保存到数据库后可以设置ID)意味着可能会意外地将其设置为随机/无效值。
我对ORM不太熟悉,对Dapper的知识为零,因此,如果我在上述任何方面都不对,请更正我。
最好的方法是什么?
我看到的代理键的问题在于,它们与业务逻辑本身的相关性为零。
这实际上是好处,而不是问题。密钥的值是实体的不可变标识符,而不管其他变化如何。我真的怀疑是否存在任何广泛使用的ORM不能轻易使用它,因为替代方法(将更改对每个子记录的键值进行级联)实施起来要困难得多。
我还建议您为难度级别添加一个值,该值允许在数据模型中表示难度不断增加的层次结构,否则就不能稳健地表示“比...更难”或“比……更容易”。