数据库设计(DDL)
Database Design (DDL)
我有一个 table 用于冰淇淋店(店)和一个 table 用于店内提供的不同口味。此外还有一个用户 table 并且该用户应该能够对口味进行评分。
Parlour 和 flavour 之间存在一对多的关系,其中 flavor 是一个弱实体。 Flavor 和 User 之间也存在多对多关系,然后创建一个新的 table 称为 Vote。
我的 DDL 脚本如下所示:
CREATE TABLE parlor (
parlor_id INTEGER AUTO_INCREMENT,
name VARCHAR(255),
street VARCHAR(255),
street_numb INTEGER,
zip INTEGER,
PRIMARY KEY (parlor_id)
);
CREATE TABLE flavour (
name VARCHAR(255),
parlor_id INTEGER,
PRIMARY KEY (name, parlor_id),
FOREIGN KEY (parlor_id) REFERENCES parlor (parlor_id)
);
CREATE TABLE user (
uid INTEGER AUTO_INCREMENT,
username VARCHAR(255) UNIQUE,
password BINARY(64),
PRIMARY KEY (uid)
);
CREATE TABLE vote (
date TIMESTAMP,
ranking INTEGER(5),
flavour VARCHAR(255),
uid INTEGER,
parlor_id INTEGER,
PRIMARY KEY (date, uid, flavour, parlor_id),
FOREIGN KEY (uid) REFERENCES user (uid),
FOREIGN KEY (flavour) REFERENCES flavour (name),
FOREIGN KEY (parlor_id) REFERENCES flavour (parlor_id)
);
我的问题是,我可以投票给客厅里根本不存在的口味。例如:
INSERT INTO vote (date, ranking, flavour, uid, parlor_id) VALUES ('...', 5, 'Chocolate', 1, 10)
在 ID 为 10 的客厅中,用户 ID 为 1 的用户对风味 'Chocolate' 的评分为 5。
但是当我这样做时...
SELECT * FROM flavour WHERE parlor_id=10;
没有味道'chocolate'
向 flavor table (flavor_id INTEGER
) 添加一个实际键,将其设置为主键并让外键引用该列。这将解决您的问题并改进您的整体设计。
您可以 "convert" 您的 name, parlor_id
键到唯一约束以保持唯一性。
那是因为你的口味PK是(name,parlor_id),但是投票只引用了其中的一部分:
FOREIGN KEY (flavour) REFERENCES flavour (name)
当然你可以做一个复杂的 FK:
FOREIGN KEY (flavour, parlour_id) REFERENCES flavour (name, parlour_id)
但实际上如果你只是用普通的PK来调味会更好:
CREATE TABLE flavour (
id INTEGER PRIMARY KEY,
name VARCHAR(255),
parlor_id INTEGER,
FOREIGN KEY (parlor_id) REFERENCES parlor (parlor_id)
);
并引用此 ID:
CREATE TABLE vote (
id INTEGER PRIMARY KEY,
date TIMESTAMP,
ranking INTEGER(5),
flavour_id INTEGER,
uid INTEGER,
parlor_id INTEGER,
FOREIGN KEY (uid) REFERENCES user (uid),
FOREIGN KEY (flavour_id) REFERENCES flavour (id)
);
我有一个 table 用于冰淇淋店(店)和一个 table 用于店内提供的不同口味。此外还有一个用户 table 并且该用户应该能够对口味进行评分。
Parlour 和 flavour 之间存在一对多的关系,其中 flavor 是一个弱实体。 Flavor 和 User 之间也存在多对多关系,然后创建一个新的 table 称为 Vote。
我的 DDL 脚本如下所示:
CREATE TABLE parlor (
parlor_id INTEGER AUTO_INCREMENT,
name VARCHAR(255),
street VARCHAR(255),
street_numb INTEGER,
zip INTEGER,
PRIMARY KEY (parlor_id)
);
CREATE TABLE flavour (
name VARCHAR(255),
parlor_id INTEGER,
PRIMARY KEY (name, parlor_id),
FOREIGN KEY (parlor_id) REFERENCES parlor (parlor_id)
);
CREATE TABLE user (
uid INTEGER AUTO_INCREMENT,
username VARCHAR(255) UNIQUE,
password BINARY(64),
PRIMARY KEY (uid)
);
CREATE TABLE vote (
date TIMESTAMP,
ranking INTEGER(5),
flavour VARCHAR(255),
uid INTEGER,
parlor_id INTEGER,
PRIMARY KEY (date, uid, flavour, parlor_id),
FOREIGN KEY (uid) REFERENCES user (uid),
FOREIGN KEY (flavour) REFERENCES flavour (name),
FOREIGN KEY (parlor_id) REFERENCES flavour (parlor_id)
);
我的问题是,我可以投票给客厅里根本不存在的口味。例如:
INSERT INTO vote (date, ranking, flavour, uid, parlor_id) VALUES ('...', 5, 'Chocolate', 1, 10)
在 ID 为 10 的客厅中,用户 ID 为 1 的用户对风味 'Chocolate' 的评分为 5。
但是当我这样做时...
SELECT * FROM flavour WHERE parlor_id=10;
没有味道'chocolate'
向 flavor table (flavor_id INTEGER
) 添加一个实际键,将其设置为主键并让外键引用该列。这将解决您的问题并改进您的整体设计。
您可以 "convert" 您的 name, parlor_id
键到唯一约束以保持唯一性。
那是因为你的口味PK是(name,parlor_id),但是投票只引用了其中的一部分:
FOREIGN KEY (flavour) REFERENCES flavour (name)
当然你可以做一个复杂的 FK:
FOREIGN KEY (flavour, parlour_id) REFERENCES flavour (name, parlour_id)
但实际上如果你只是用普通的PK来调味会更好:
CREATE TABLE flavour (
id INTEGER PRIMARY KEY,
name VARCHAR(255),
parlor_id INTEGER,
FOREIGN KEY (parlor_id) REFERENCES parlor (parlor_id)
);
并引用此 ID:
CREATE TABLE vote (
id INTEGER PRIMARY KEY,
date TIMESTAMP,
ranking INTEGER(5),
flavour_id INTEGER,
uid INTEGER,
parlor_id INTEGER,
FOREIGN KEY (uid) REFERENCES user (uid),
FOREIGN KEY (flavour_id) REFERENCES flavour (id)
);