为什么这个 Knex 迁移不强制列是唯一的?

Why is this Knex migration not forcing a column to be unique?

我正在使用此 Knex 迁移创建 SQLite 数据库。当我在 SQLiteStudio 中查看数据库时,它并不表示电子邮件列是唯一的。有没有我遗漏的错误?

exports.up = function (knex) {
    return knex.schema
        .createTable('users', users => {
            users.increments();
            users.string('email', 128).unique().notNullable();
            users.string('password', 256).notNullable();
        })

生成的 DDL 代码:

CREATE TABLE users (
    id       INTEGER       NOT NULL
                           PRIMARY KEY AUTOINCREMENT,
    email    VARCHAR (128) NOT NULL,
    password VARCHAR (256) NOT NULL
);

我尝试过但无效的替代方案:

-unique()和notNullable()的切换顺序

users.string('email', 128).notNullable().unique()

-创建单独的行以添加唯一约束

        .createTable('users', users => {
            users.increments();
            users.string('email', 128).notNullable();
            users.string('password', 256).notNullable();
            users.unique('email');
        })

它是独一无二的,只是您不会在 CREATE TABLE 声明中看到它。 SQLite 通过 creating an indexUNIQUE 限定符设置了 UNIQUE 约束。以下面的 Knex 迁移为例:

exports.up = knex =>
  knex.schema.debug().createTable("users", t => {
    t.increments("id");
    t.string("name").unique();
  });

注意 debug(),如果您想查看正在生成的内容 SQL,这非常方便。这是调试输出:

[
  {
    sql: 'create table `users` (`id` integer not null ' +
      'primary key autoincrement, `name` ' +
      'varchar(255))',
    bindings: []
  },
  {
    sql: 'create unique index `users_name_unique` on `users` (`name`)',
    bindings: []
  }
]

如您所见,发出了第二条语句来创建 UNIQUE 约束。如果我们现在去查看数据库,我们会看到如下内容:

07:48 $ sqlite3 dev.sqlite3
sqlite> .dump users
BEGIN TRANSACTION;
CREATE TABLE `users` (`id` integer not null primary key autoincrement,
  `name` varchar(255));
CREATE UNIQUE INDEX `users_name_unique` on `users` (`name`);
COMMIT;

顺便说一句,您可能希望对用户电子邮件的可能长度进行更多研究。以 this answer 为起点。