mysql - 我怎样才能最好地保持表中两列之间的完整性?

标签 mysql database-design referential-integrity data-integrity

假设,我有一个名为 CategoryENUM 列和一个名为 SubcategoryENUM 列。有时我会想单独在 CategorySELECT,这就是它们被分开的原因。

CREATE TABLE `Bonza` (
   `EventId`     INT UNSIGNED NOT NULL AUTO_INCREMENT,
   `Category`    ENUM("a", "b", "c") NOT NULL,
   `Subcategory` ENUM("x", "y", "z") NOT NULL,

   PRIMARY KEY(`EventId`)
) ENGINE=InnoDB;

但并非所有子类别都适用于所有类别(例如,"z" 仅对 "a""b" 有效), 令我恼火的是,这个约束没有融入表格的设计中。如果 MySQL 具有某种“对”类型(其中该类型的列可在值的前导子序列上建立索引),那么这就不是问题。

如果我想保持类别和子类别之间的完整性,我就不得不在触发器中编写长条件语句。还是我最好离开它?你会怎么做?

我认为最面向关系的方法是存储一个 EventCategoryId,并将其映射到一个包含所有有效事件类型对的表,并在每次我想查找时加入该表事件类别的含义。

CREATE TABLE `Bonza` (
   `EventId`         INT UNSIGNED NOT NULL AUTO_INCREMENT,
   `EventCategoryId` INT UNSIGNED NOT NULL,

   PRIMARY KEY(`EventId`),
   FOREIGN KEY `EventCategoryId` REFEFRENCES(`EventCategories`.`EventCategoryId`)
     ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB;

CREATE TABLE `EventCategories` (
   `EventCategoryId` INT UNSIGNED NOT NULL,
   `Category`    ENUM("a", "b", "c") NOT NULL,
   `Subcategory` ENUM("x", "y", "z") NOT NULL,

   PRIMARY KEY(`EventCategoryId`)
) ENGINE=InnoDB;
-- Now populate this table with valid category/subcategory pairs at installation

我可以做更简单的事情吗?对于 INSERTBonza 中,此查找可能会降低调用代码的复杂性和性能,不是吗?

最佳答案

假设您的类别和子类别不会经常更改,并且假设您愿意接受重大更新,那么您可以执行以下操作:

使用EventCategories 表来控制类别和子类别之间的层次约束。该表的主键应该是包含类别子类别复合键。在您的 Bonza 表中引用此表。 Bonza 中的外键恰好包含您要作为筛选依据的两列,因此您无需加入即可获得所需内容。也不可能分配无效的组合。

CREATE TABLE `Bonza` (
   `EventId`         UNSIGNED INT NOT NULL AUTO_INCREMENT,
   `Category`        CHAR(1) NOT NULL,
   `Subcategory`     CHAR(1) NOT NULL,

   PRIMARY KEY(`EventId`),
   FOREIGN KEY `Category`, `Subcategory` 
   REFEFRENCES(`EventCategories`.`Category`, `EventCategories`.`Subcategory`)
     ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB;

CREATE TABLE `EventCategories` (
   `EventCategoryId` UNSIGNED INT NOT NULL,
   `Category`    CHAR(1) NOT NULL,
   `Subcategory` CHAR(1) NOT NULL,

   PRIMARY KEY(`Category`, `Subcategory`)
) ENGINE=InnoDB;

关于mysql - 我怎样才能最好地保持表中两列之间的完整性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22711747/

相关文章:

php - phpMyAdmin 的单点登录

database - 是否有任何用于 mysql/sqlite/postgresql 的 SQL 设计器(用于 linux 或基于 web 的)?

mysql - 为多对多关系建模的正确方法

sql-server - 是否可以将参照完整性检查推迟到 SQL Server 中的事务结束?

sql - PostgreSQL 导入,如果不满足约束设置 null

sql - SET CONSTRAINTS ALL DEFERRED 未按预期工作

javascript - 在动态创建的 HTML 表中调用 PHP 函数

php - 从表中获取多个ID的最后插入数据?

MySQL 查询选项定义中的 PHP 下拉框

sql - 如何设计映射同一实体的表?