Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SQL 0到1,或布尔值_Sql_Database_Database Design - Fatal编程技术网

SQL 0到1,或布尔值

SQL 0到1,或布尔值,sql,database,database-design,Sql,Database,Database Design,我目前正在将大量的用户数据从CSV电子表格迁移到SQL数据库,设计模式以及所有的jazz 此时,Users表如下所示: CREATE TABLE Users ( id INTEGER NOT NULL AUTO_INCREMENT, name VARCHAR(48) NOT NULL, alias VARCHAR(24) NOT NULL UNIQUE, email VARCHAR(128) NOT NULL,

我目前正在将大量的用户数据从CSV电子表格迁移到SQL数据库,设计模式以及所有的jazz

此时,Users表如下所示:

CREATE TABLE Users
(
    id      INTEGER NOT NULL AUTO_INCREMENT,

    name        VARCHAR(48) NOT NULL,
    alias       VARCHAR(24) NOT NULL UNIQUE,
    email       VARCHAR(128) NOT NULL,

    date_of_birth   DATE,
    location    VARCHAR(24) NOT NULL,

    date_joined DATE,

    ...

    PRIMARY KEY (id)
);
我们(集团)正期待着很快测试针对特定事件和评论的电子邮件订阅服务;这将通过查看数据库中的订阅用户来管理

我最初的想法是只向Users表中添加一个布尔值,表示它们是否已订阅,但像这样编辑模式似乎是一种糟糕的做法

我的第二个想法是:

CREATE TABLE Subscribers
(
    uid     INTEGER NOT NULL,
    PRIMARY KEY (uid)
    FOREIGN KEY (uid) REFERENCES Users(id)
);
这两种方法的优点和缺点是什么?哪一个最适合我的情况,因为测试可能是实验性的

(旁注:用户没有uid列。)


订阅者不需要代理密钥。它可以只有一列,这是
用户(id)
上的主键和外键。您最好使用布尔值。。。再想一想,如果用户想要取消订阅,你必须将其从数据库中删除,这是一个非常糟糕的主意


在这一点上,布尔值可以更好地确定该用户是否允许您向他们发送电子邮件

哪种操作过程是合适的,这在很大程度上取决于预期的用例。如果您只能订阅一份时事通讯,则应首选布尔标志版本,因为使用

select * from User where subscribed = 1 
而不是与可能较大的
订阅者
表进行联接。但是,如果您可以订阅多个新闻稿,这意味着在用户表中为每个新闻稿添加一列(例如
订阅产品公告
订阅度假新闻稿
,等等)。如果您拥有大量用户(数百万),如果您遇到性能问题,这可能仍然是一个选项,但除非您使用
订阅者
表确实遇到性能问题,否则最好使用该表,因为您可以添加更多新闻稿,而无需始终更改数据库架构。这需要您用一个字段扩展
订阅者
表,不过:

CREATE TABLE Subscribers
(
    id      LONG PRIMARY KEY AUTO_INCREMENT,
    newsletterId INTEGER NOT NULL  -- the ID of the newsletter that the user is subscribed to
    uid     INTEGER NOT NULL,
    FOREIGN KEY (uid) REFERENCES Users(uid)
);

我也会在
订阅者的
id
列中选择
,因为订阅可能来来往往,最终你可能会达到
整数的20亿上限。可能将该表重命名为订阅也是一个好主意,因为它实际上包含订阅而不是订阅。

订阅表方法的优点包括:

  • 它是一个更高的,实际上是最高的标准形式,是6NF
  • 它更具可移植性,例如,并非所有SQL产品都具有布尔类型
这其中还有更多的原因


不过,发布的
Subscribers
表有一些缺陷。
uid
列应具有唯一的约束。“自动增量”列是多余的。外键可能在删除级联上具有引用操作
(更新级联上的
在将来可能会有用)。

这并不能回答我的问题,最好作为一个注释。虽然我对你将如何做你提议的事情感兴趣(只有1列PK FK)对不起,我本想扩大我的答案,但在我有机会之前,我被转移到了其他问题上。你只会从订阅者表中删除,而不会从其他任何地方删除。。。所以你的第二个理由没有意义。我的观点是,你无论如何都不应该从数据库中删除;因此,从安全角度看,我看不出删除表和删除列之间的区别。Adam“无论如何都不应该从数据库中删除”是胡说八道。如果行的存在表示与位列值的赋值具有相同的逻辑意义,那么删除行对于数据库中的数据意味着什么没有功能上的区别。有些硬性规定“永远不应该删除数据”是不可支持的;那我就用布尔值吧!干杯。@Daniel你提到的答案中有什么遗漏吗?它涵盖了你的大部分观点?我也很乐意添加缺少的部分。我认为布尔值是错误的答案。当您想要存储有关订阅的数据而不仅仅是订阅的事实时,您会突然后悔位列的决定。不要使用数据类型“text”,因为它已被弃用。使用varchar(max)使用varchar(20)或任何需要的长度我更新了我的代码以反映您提出的一些建议;不知道你说的删除级联是什么意思;丹尼尔:当用户从
用户
表中删除时,删除级联
上的
将自动从引用表
订阅者
中删除他们。有关更多详细信息,请参阅。