Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/82.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_Django_Sqlite_Database Design_Foreign Key Relationship - Fatal编程技术网

Sql 针对多种实体类型的最佳数据库设计

Sql 针对多种实体类型的最佳数据库设计,sql,django,sqlite,database-design,foreign-key-relationship,Sql,Django,Sqlite,Database Design,Foreign Key Relationship,我正在开发一个web应用程序,我必须设计它的数据库。有一部分对我来说不是很简单,所以经过一些思考和研究,我有了很多想法。但这两种方法似乎都不完全合适,所以我不确定应该实施哪种方法以及为什么 简化问题如下所示: 我有一位餐桌老师。根据与各自领域和学科的关系,有两种类型的教师: 与某一领域相关的教师,该领域与某一类别相关 与某个领域无关,但与某个类别直接相关的教师 我最初的想法是有两个可为空的外键,一个指向表字段,另一个指向表类别。但是在这种情况下,我如何确保一个是空的,另一个不是空的 另一个想法是

我正在开发一个web应用程序,我必须设计它的数据库。有一部分对我来说不是很简单,所以经过一些思考和研究,我有了很多想法。但这两种方法似乎都不完全合适,所以我不确定应该实施哪种方法以及为什么

简化问题如下所示: 我有一位餐桌老师。根据与各自领域和学科的关系,有两种类型的教师:

  • 与某一领域相关的教师,该领域与某一类别相关
  • 与某个领域无关,但与某个类别直接相关的教师
  • 我最初的想法是有两个可为空的外键,一个指向表字段,另一个指向表类别。但是在这种情况下,我如何确保一个是空的,另一个不是空的

    另一个想法是创建一个层次结构,从表Teacher(is-a关系)派生出两种类型的Teacher表,但我找不到任何有用的教程


    我正在使用Django和SQLite db开发应用程序。好的,你的评论让它更清晰了:

    如果教师只属于一个类别,则应直接将其保存在教师表中:

    其次,每个教师都属于“一个或零个”字段。如果这是确定的,您应该使用一个可为空的FieldID列。此选项已设置或保持为空

    Category (CategoryID, Name, ...)
    Field (FieldID,Name,...)
    Teacher (TeacherID,FieldID [NULL FK],CategoryID [NOT NULL FK], FirstName, Lastname, ...)
    
    备注:这与我上次回答的映射表几乎相同。唯一的区别是,你会有一个严格的限制,你的“完全一个”或“完全没有或一个”。。。根据我的经验,我还是更喜欢开放式的方法。使用独特的索引(包括TeacherID列)很容易实施规则。迟早你可能不得不重新构建这个

    继续时,一个类别与“零个或多个”字段相关。有两种方法:

    将CategoryID列添加到字段表(非空FK)。这样,您可以使用不同的CategoryId(组合唯一索引!)多次定义字段。一个类别的字段列表,您只需向字段表查询具有给定CategoryID的所有字段即可得到

    在我看来,更好的是映射表类别字段。如果您强制使用一个唯一的FieldID,您将可以确保没有字段被映射两次。并在CategoryID和FieldID的组合上添加唯一索引

    SELECT可以是这样的(SQL Server语法,未经测试):

    这是编辑前的答案: 即使我对这个概念不是很清楚,我也会尽力帮助你

    Teacher-Table: TeacherID, person's data (name, address...), ...
    Category-Table: CategoryID, category title, ... 
    Field-Tabls: FieldID, field title, ...
    
    您可以说,字段在所有情况下都绑定到一个类别。如果在所有情况下都是同一类别,则应在字段表中将该类别设置为FK列。如果一个字段的类别有可能因上下文的不同而有所不同,那么您不应该

    与教师相同:如果教师绑定到一个类别,请在教师表中设置一个FK列,否则不设置

    至少有一个映射表是最灵活的:

    (SQL Server语法)

    更好的概念是使用映射表FieldCategory,并通过外键将该表映射到上面的映射表。这样做可以避免无效的字段类别组合


    希望这有助于…

    使用TeacherID、FieldID和CategoryID的映射表如何,所有这些都带有外键。使用约束检查“若设置了字段,则也必须设置类别”和索引以强制组合的唯一性。。。这允许将教师绑定到不同的字段/类别…查看答案是否符合您的目的。@Shnugo在这种设计中,确保每位教师只有一个条目的最佳方法是什么?如果我的答案有帮助,请投票支持,如果有助于您解决问题,请将其标记为已接受的答案,谢谢!每一位教师只属于一个类别。每个教师都属于一个或零个字段。每个类别由零个或多个字段组成。如果一个教师绑定到一个字段,我们可以从这个关系中获得类别。在创建ER图时,我将其绘制为三元关系,但我不知道设计模型的最佳方法。。
    Teacher-Table: TeacherID, person's data (name, address...), ...
    Category-Table: CategoryID, category title, ... 
    Field-Tabls: FieldID, field title, ...
    
    CREATE TABLE TeacherFieldCategory
    (
    --A primary key to identify this row. This is not needed actually, but it will serve as clustered key index as a lookup index...
     TeacherFieldCategoryID INT IDENTITY NOT NULL CONSTRAINT PK_TeacherFieldCategory PRIMARY KEY
    --Must be set
    ,TeacherID INT NOT NULL CONSTRAINT FK_TeacherFieldCategory_TeacherID FOREIGN KEY REFERENCES Teacher(TeacherID)
    --Field may be left NULL
    ,FieldID INT NULL CONSTRAINT FK_TeacherFieldCategory_FieldID FOREIGN KEY REFERENCES Field(FieldID)
    --Must be set. This makes sure, that a teacher ever has a category and - if the field is set - the field will have a category
    ,CategoryID INT NOT NULL CONSTRAINT FK_TeacherFieldCategory_CategoryID FOREING KEY REFERENCES Category(CategoryID)
    );
    --This unique index will ensure, that each combination will exist only once.
    CREATE UNIQUE INDEX IX_TeacherFieldCategory_UniqueCombination ON TeacherFieldCategory(TeacherID,FieldID,CategoryID);