如何创建和规范这个 SQL 关系数据库?

How to create and normalise this SQL relational database?

我正在尝试设计一个 SQL 精简版数据库。我已经在纸上快速设计了我想要的东西。

到目前为止,我有一个 table 包含以下列:

我最纠结的专栏是list_of_items。我知道关系数据库没有允许列表的列,您必须使用该信息创建第二个 table 以规范化数据库。我查看了一些堆栈溢出答案,包括 this 一个,它说您不能将列表存储在列中,但我无法将已接受的答案应用到我的案例中。

我考虑过有一个辅助 table,它会为属于 user_id 的每个项目 ID 设置一行,在这种情况下,主键将是项目 ID 的组合和 user_id,但是,我不确定这是否是理想的处理方式。

考虑以下包含 3 个表的架构:

CREATE TABLE users (
  user_id INTEGER PRIMARY KEY, 
  user TEXT NOT NULL,
  number_of_items_allowed INTEGER NOT NULL CHECK(number_of_items_allowed >= 0)
);

CREATE TABLE items (
  item_id INTEGER PRIMARY KEY, 
  item TEXT NOT NULL
);

CREATE TABLE users_items (
  user_id INTEGER NOT NULL REFERENCES users(user_id) ON UPDATE CASCADE ON DELETE CASCADE, 
  item_id INTEGER NOT NULL REFERENCES items (item_id) ON UPDATE CASCADE ON DELETE CASCADE, 
  PRIMARY KEY(user_id, item_id)
);

对于此模式,您需要 users_items 上的 BEFORE INSERT 触发器,它通过比较用户的 number_of_items_allowed 与当前的数量来检查是否可以为用户插入新项目用户拥有的项目:

CREATE TRIGGER check_number_before_insert_users_items 
BEFORE INSERT ON users_items
BEGIN
   SELECT
     CASE
       WHEN (SELECT COUNT(*) FROM users_items WHERE user_id = NEW.user_id) >=
            (SELECT number_of_items_allowed FROM users WHERE user_id = NEW.user_id)
         THEN RAISE (ABORT, 'No more items allowed')
     END;
END;

您将需要另一个触发器来检查 number_of_items_allowed 何时更新,如果新值小于此用户的当前项目数:

CREATE TRIGGER check_number_before_update_users 
BEFORE UPDATE ON users
BEGIN
   SELECT
     CASE
       WHEN (SELECT COUNT(*) FROM users_items WHERE user_id = NEW.user_id) > NEW.number_of_items_allowed
         THEN RAISE (ABORT, 'There are already more items for this user than the value inserted')
     END;
END;

参见demo