将此数据存储在MySQL模式中的正确方法是什么?

Eth*_*len 8 mysql schema database-design relational-database database-schema

我有一个movieMySQL数据库.A movie包含永不更改的数据属性,如下所示:

  • 条形码:025192018626
  • 格式:DVD
  • 运行时间:121分钟
  • 光盘:1
  • 标题:12只猴子
  • 年份:1995年

它是表格中的一行.

但是我想让我的用户对这些信息进行完全的自定义,以防万一根据它们不正确,或者他们只是想以某种方式修改数据的显示方式.我不在乎为什么,我只是想让我的用户选择他们想要的东西.

假设用户#1想要将他们的标题更改为"12 Monkeys(Shelf 1)",这就是他们改变的全部内容.

让我们说用户#2想要将DVD改为数字拷贝.

让我们说用户#3想要将他们的标题改为"十二只猴子",因为它是替代标题.

等等

我的问题是,我该如何存储只是一个更改为一个字段只有该用户名,而不需要修改原始数据?在一个单独的相同表中,除了一个字段外,所有字段都是完全相同的数据?或者我可以在某处存储一个单独的更改(例如标题)并返回movie其余的数据?

设计这个的正确方法是什么,特别是如果我有1000个用户主要在一两个字段上进行自定义数据修改?

Bar*_*mar 13

而不是每部电影的一行,使用属性值表.然后为此添加一个指定用户的附加字段,该字段将0用于原始默认值.所以表格如下:

MovieID UserID  Attribute   Value
1       0       Title       12 Monkeys
1       0       Format      DVD
1       1       Title       Twelve Monkeys
Run Code Online (Sandbox Code Playgroud)

然后获取标题的查询将如下所示:

SELECT MovieID, IFNULL(my.Value, default.Value) AS title
FROM movies AS default
LEFT JOIN movies AS my ON default.MovieID = my.MovieID AND my.Attribute = 'Title' AND my.userID = @user
WHERE default.UserID = 0 AND default.Attribute = 'Title'
Run Code Online (Sandbox Code Playgroud)

一些数据库设计者还喜欢使用AttributeID而不是字符串作为属性名称,以及将属性名称映射到ID的单独表.


Ric*_*mes 7

我建议没有'正确'的方式.但你可能会喜欢这个......

  • 你的Movie桌子保持原样.(我假设有一个id.)
  • 另一个表,UserMovie具有相同的列,除了:
    • 所有列,除了idNULL
    • 它有另一个专栏: user NOT NULL
    • PRIMARY KEY(id, user)

当用户修改某些内容时,用于INSERT INTO UserMovie .. ON DUPLICATE KEY UPDATE ..更改他想要设置的任何字段.请注意,INSERT如果不存在,IODKU将为新行或UPDATE现有行(因为用户正在修改另一列).例如,要仅覆盖id = $ id的"标题",

INSERT INTO UserMovie
    (id, title)
    VALUES
    ($id, '$title')
ON DUPLICATE KEY UPDATE
    title = '$title';
Run Code Online (Sandbox Code Playgroud)

当用户想要看到他拥有的东西时,

SELECT  coalesce(u.title, m.title) AS title,
        coalesce(u.format, m.format) AS format,
        coalesce...
    FROM Movie AS m
    LEFT JOIN UserMovie AS u
            ON u.id = m.id
            AND u.user = $user
    WHERE m.id = $id;
Run Code Online (Sandbox Code Playgroud)

COALESCE静静的图片或者u.xxx如果NOT NULL,或m.xxx.

这种设计具有非常紧凑的优点.(NULLs几乎没有空间.)

如果用户两次更改"标题",则仅保留最后一个版本.

要"恢复"标题:

UPDATE UserMovie SET title = NULL
    WHERE id = $id
      AND user = $user;
Run Code Online (Sandbox Code Playgroud)

(当然,这可能会留下一排NULLs,但其余的代码仍然有效.)