我不确定如何表达这个问题,所以我将说明表格并解释我想要实现的目标。
-- static table of the entity classes supported by the application
create table entity_type (
id integer not null auto_increment,
name varchar(30) not null,
primary key(id)
);
-- static table of statuses supported by the application
create table entity_status (
id integer not null auto_increment,
name varchar(30) not null,
primary key(id)
);
-- table of valid combinations
create table entity_type_entity_status_link (
entity_type_id integer not null,
entity_status_id integer not null,
unique key(entity_type_id, entity_status_id),
foreign key(entity_type_id) references entity_type(id),
foreign key(entity_status_id) references entity_status(id),
);
-- The tables where user types and statuses are defined
create table user_type (
id integer not null auto_increment,
name varchar(30) not null,
entity_type_id integer not null,
primary key(id),
foreign key(entity_type_id) references entity_type(id)
);
create table user_status (
id integer not null auto_increment,
name varchar(30) not null,
entity_status_id integer not null,
primary key(id),
foreign key(entity_status_id) references entity_status(id)
);
-- table of valid pairs
create table user_type_user_status_link (
user_type_id integer not null,
user_status_id integer not null,
unique key(user_type_id, user_status_id),
foreign key(user_type_id) references user_type(id),
foreign key(user_status_id) references user_status(id),
);
这些表背后的基本前提是系统支持核心类型和状态,用户可以创建自己的用户类型和源自这些类型的状态。
我的问题是我看不到在user_type_user_status_link表上创建任何数据库约束的方法,以确保您不能插入file_type - file_status对,其中parent entity_type - entity_status本身无效。或者这是必须用触发器完成的事情。
答案 0 :(得分:1)
这些表背后的基本前提是系统支持核心 类型和状态,用户可以创建自己的用户类型 和来自这些的雕像。
虽然这听起来似乎是表面上值得称赞的目标,但其效果是将数据库设计委派给您的用户。数据库设计,因为您希望将外键引用设置为entity_type_entity_status_link
中的行子集的效果意味着每个子集都是一个未命名的事实表。
这种方法永远不会结束。
您开发的是“One True Lookup Table”。谷歌认为OTLT是反模式的原因有很多。
最好的解决方案是对表格中的真实事物进行建模。 (实体并不是真实的东西。它是真实事物的抽象。)某些东西都是
create table file_status (
file_status varchar(30) primary key
);
或
create table file_status (
file_status_id integer primary key,
file_status varchar(30) not null unique
);
可以很好地处理文件状态。
对于第二个,您可以将外键引用设置为id号(节省空间,需要额外的连接)或状态文本(占用更多空间,消除连接)。请注意,您需要对状态文本使用唯一约束;您的原始设计允许用户多次输入相同的文本。 (最终可能有30行,其中entity_type.name
是'文件'。
答案 1 :(得分:0)
你应该使用触发器。
MySQL不支持阻止你想要的表单的约束。