带有varchar主键字段的mysql表

问题描述 投票:0回答:5

我创建了具有以下结构的用户表

CREATE TABLE `users` (
   `id` varchar(36) NOT NULL,
   `first_name` varchar(100) NOT NULL,
   `last_name` varchar(100) NULL,
   `email` varchar(100) NOT NULL,
   `password` varchar(100) NOT NULL,
   PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

我只想在插入新行时自动填充id值。

mysql cakephp phpmyadmin
5个回答
1
投票

如果您确实希望与触发器一起生成uuid,那么您的表设计会遇到一些问题

drop table if exists t;
CREATE TABLE t (
   `id` varchar(36) not null,
   `first_name` varchar(100) NOT NULL,
   `last_name` varchar(100) NULL,
   `email` varchar(100) NULL,
   `password` varchar(100) NULL ,
    PRIMARY KEY (`id`)
) ;

drop trigger if exists t;
delimiter $$
create trigger t before insert on t
for each row 

begin

        set new.id = (select uuid());

end $$

delimiter ;
truncate table t;
insert into t (first_name) values (1),(2);
ERROR 1364 (HY000): Field 'id' doesn't have a default value

并且您不能使用默认值,因为尝试插入(2)时会发生重复错误;并且您不能将not null更改为null,因为主键必须具有值。

您可以将id更改为null并将主键更改为唯一键

drop table if exists t;
CREATE TABLE t (
   `id` varchar(36) null,
   `first_name` varchar(100) NOT NULL,
   `last_name` varchar(100) NULL,
   `email` varchar(100) NULL,
   `password` varchar(100) NULL ,
    unique key (`id`)
) ;

drop trigger if exists t;
create trigger t before insert on t
for each row 
        set new.id = (select uuid());


truncate table t;
insert into t (first_name) values (1),(2);
select * from t;
+--------------------------------------+------------+-----------+-------+----------+
| id                                   | first_name | last_name | email | password |
+--------------------------------------+------------+-----------+-------+----------+
| 874bd297-adeb-11e8-b404-b8aeed249e19 | 1          | NULL      | NULL  | NULL     |
| 874bda27-adeb-11e8-b404-b8aeed249e19 | 2          | NULL      | NULL  | NULL     |
+--------------------------------------+------------+-----------+-------+----------+
2 rows in set (0.00 sec)

1
投票

试试id int(11) NOT NULL AUTO_INCREMENT,

CREATE TABLE `users` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `first_name` varchar(100) NOT NULL,
   `last_name` varchar(100) NULL,
   `email` varchar(100) NOT NULL,
   `password` varchar(100) NOT NULL,
   PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

0
投票

您正在尝试使VARCHAR列自动递增。你不能那样做。

包含整数文本的VARCHAR列非常难以正确排序。

在MySQL中,自动填充(自动增量)ID列必须具有整数数据类型。

尝试改变

    `id` varchar(36) NOT NULL,

    `id` UNSIGNED BIGINT NOT NULL AUTO_INCREMENT,

(我选择了UNSIGNED BIGINT,因为它是可用的最大整数,你在VARCHAR(36)中选择的36使得它看起来像你期望在这个表中有大量的行。但UNSIGNED INT会给你四个gigarows,这是可能就够了。)

如果您选择使用触发器或其他方法为VARCHAR ID列生成自动增量值,则必须对事务执行大量繁重工作以避免重复值的可能性。

如果您的客户端软件必须将此列视为VARCHAR,则可以在视图中执行或选择。 SELECT CAST(id AS VARCHAR(36)) id做到了。


0
投票

假设您想要为主键自动生成GUID,这在MySql中只能使用触发器。

CREATE TRIGGER before_insert_users
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
  IF new.id IS NULL THEN
    SET new.id = uuid();
  END IF;
END

更多信息可以在这里找到:https://www.electrictoolbox.com/mysql-guid-uuid-default-column/


0
投票

Cookbook 3.x说:

您可以使用char(36),而不是使用自动增量键作为主键。每当使用Table :: save()方法保存新记录时,CakePHP将使用唯一的36个字符UUID(Text :: uuid)。

意味着每当使用Table :: save()方法保存新记录时,CakePHP都会自动保存唯一的36个字符UUID(Text :: uuid)。

只是改变

 id varchar(36) NOT NULL

 id char(36) NOT NULL

希望这会有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.