简体   繁体   English

如何在SQL Server中建模互斥关系

[英]How to model a mutually exclusive relationship in SQL Server

I have to add functionality to an existing application and I've run into a data situation that I'm not sure how to model. 我必须在现有应用程序中添加功能,并且我遇到了数据情况,我不确定如何建模。 I am being restricted to the creation of new tables and code. 我被限制为创建新的表和代码。 If I need to alter the existing structure I think my client may reject the proposal.. although if its the only way to get it right this is what I will have to do. 如果我需要改变现有的结构,我认为我的客户可能会拒绝该提案。虽然如果它是唯一能够做到正确的方法,那么我将不得不这样做。

I have an Item table that can me link to any number of tables, and these tables may increase over time. 我有一个Item表,可以链接到任意数量的表,这些表可能会随着时间的推移而增加。 The Item can only me linked to one other table, but the record in the other table may have many items linked to it. Item只能链接到另一个表,但另一个表中的记录可能有很多项链接到它。

Examples of the tables/entities being linked to are Person , Vehicle , Building , Office . 链接到的表/实体的示例是PersonVehicleBuildingOffice These are all separate tables. 这些都是单独的表。

Example of Items are Pen , Stapler , Cushion , Tyre , A4 Paper , Plastic Bag , Poster , Decoration" 项目的例子是PenStaplerCushionTyreA4 PaperPlastic BagPosterDecoration"

For instance a Poster may be allocated to a Person or Office or Building . 例如,可以将Poster分配给PersonOfficeBuilding In the future if they add a Conference Room table it may also be added to that. 将来如果他们添加Conference Room表,也可以添加到Conference Room表中。

My intital thoughts are: 我的初步想法是:

Item
{
  ID,
  Name
}

LinkedItem
{
  ItemID,
  LinkedToTableName,
  LinkedToID
}

The LinkedToTableName field will then allow me to identify the correct table to link to in my code. 然后, LinkedToTableName字段将允许我在我的代码中标识要链接到的正确表。

I'm not overly happy with this solution, but I can't quite think of anything else. 我对这个解决方案并不是很满意,但我不能想到其他任何事情。 Please help! 请帮忙! :) :)

Thanks! 谢谢!

It is not a good practice to store table names as column values. 将表名存储为列值不是一个好习惯。 This is a bad hack. 这是一个糟糕的黑客。

There are two standard ways of doing what you are trying to do. 做你想做的事有两种标准方法。 The first is called single-table inheritance . 第一种称为单表继承 This is easily understood by ORM tools but trades off some normalization. ORM工具很容易理解这一点,但会进行一些规范化。 The idea is, that all of these entities - Person , Vehicle , whatever - are stored in the same table, often with several unused columns per entry, along with a discriminator field that identifies what type the entity is. 这个想法是,所有这些实体 - PersonVehicle ,等等 - 都存储在同一个表中,每个条目通常有几个未使用的列,以及一个识别实体是什么类型的鉴别器字段。

The discriminator field is usually an integer type, that is mapped to some enumeration in your code. discriminator字段通常是整数类型,映射到代码中的某个枚举。 It may also be a foreign key to some lookup table in your database, identifying which numbers correspond to which types ( not table names, just descriptions). 它也可能是数据库中某些查找表的外键,用于标识哪些数字对应于哪些类型( 不是表名,只是描述)。

The other way to do this is multiple-table inheritance , which is better for your database but not as easy to map in code. 另一种方法是使用多表继承 ,这对您的数据库更好,但不容易在代码中映射。 You do this by having a base table which defines some common properties of all the objects - perhaps just an ID and a name - and all of your "specific" tables ( Person etc.) use the base ID as a unique foreign key (usually also the primary key). 你可以通过一个基表来定义所有对象的一些常见属性 - 可能只是一个ID和一个名称 - 并且所有“特定”表( Person等)都使用基本ID作为唯一的外键(通常也是主键)。

In the first case, the exclusivity is implicit, since all entities are in one table. 在第一种情况下,排他性是隐含的,因为所有实体都在一个表中。 In the second case, the relationship is between the Item and the base entity ID, which also guarantees uniqueness. 在第二种情况下,关系在Item基本实体ID之间,这也保证了唯一性。

Note that with multiple-table inheritance, you have a different problem - you can't guarantee that a base ID is used by exactly one inheritance table. 请注意,对于多表继承,您有一个不同的问题 - 您不能保证只有一个继承表使用基本ID。 It could be used by several, or not used at all. 它可以被几个使用,或根本不使用。 That is why multiple-table inheritance schemes usually also have a discriminator column, to identify which table is "expected." 这就是为什么多表继承方案通常也有一个鉴别器列,以识别哪个表是“预期的”。 Again, this discriminator doesn't hold a table name, it holds a lookup value which the consumer may (or may not) use to determine which other table to join to. 同样,该鉴别器不具有表名,它保持查找值,消费者可以(或可能不)使用该查找值来确定要加入哪个其他表。

Multiple-table inheritance is a closer match to your current schema, so I would recommend going with that unless you need to use this with Linq to SQL or a similar ORM. 多表继承与您当前的模式更接近,因此我建议使用它,除非您需要将其与Linq to SQL或类似的ORM一起使用。

See here for a good detailed tutorial: Implementing Table Inheritance in SQL Server . 请参阅此处以获取详细的详细教程: 在SQL Server中实现表继承

Find something common to Person , Vehicle , Building , Office . 找到车辆建筑办公室常见的东西。 For the lack of a better term I have used Entity . 由于缺乏更好的术语,我使用了Entity Then implement super-type/sub-type relationship between the Entity and its sub-types. 然后实现Entity及其子类型之间的超类型/子类型关系。 Note that the EntityID is a PK and a FK in all sub-type tables. 请注意, EntityID是所有子类型表中的PKFK Now, you can link the Item table to the Entity (owner). 现在,您可以将Item表链接到Entity (所有者)。 In this model, one item can belong to only one Entity ; 在此模型中,一个项目只能属于一个实体 ; one Entity can have (own) many items . 一个实体可以拥有(拥有)许多项目

model_mutually_exclusive_01

your link table is ok. 你的链接表没问题。

the trouble you will have is that you will need to generate dynamic sql at runtime. 你将遇到的麻烦是你需要在运行时生成动态sql。 parameterized sql does not typically allow the objects inthe FROM list to be parameters. 参数化的sql通常不允许FROM列表中的对象成为参数。

i fyou want to avoid this, you may be able to denormalize a little - say by creating a table to hold the id (assuming the ids are unique across the other tables) and the type_id representing which table is the source, and a generated description - eg the name value from the inital record. 我想要避免这种情况,你可以稍微反规范 - 比如通过创建一个表来保存id(假设id在其他表中是唯一的)和type_id表示哪个表是源,以及生成的描述 - 例如来自初始记录的名称值。

you would trigger the creation of this denormalized list when the base info is modified, and you could use that for generalized queries - and then resort to your dynamic queries when needed at runtime. 当修改基本信息时,您将触发创建此非规范化列表,并且可以将其用于通用查询 - 然后在运行时需要时使用动态查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM