2011-12-14 93 views
3

嗨,我是一个在网络开发领域的全新手。我想创建一个只有一条记录的管理员登录表(因为只有一个管理员)。我想知道是否有可能设置MySQL以某种方式限制一个特殊的表只有一个记录?是否有可能限制一个表只有一个记录在mysql中?

+1

对该表进行插入触发 – chance 2011-12-14 10:59:43

+1

您无法使用MySQL进行创建。你能解释一下你为什么要这样做吗? – pltvs 2011-12-14 11:00:09

回答

1

有很多方法可以做到比数据库中的“强制一行”更好。

  1. 创建一个用户表并在其中创建一个字段,该字段是将用户标识为管理员的标志。这可能是简单的:

    create table users (id int not null primary key auto_increment, name varchar(20), is_admin bool default 0);

    然后你只需设置is_admin1一个管理员和搜索管理员:

    select id,name from users where is_admin;

    不属于管理员的所有用户:

    select id,name from users where not is_admin;

  2. 创建另一张使用外键关系将用户标识为管理员的表。

    create table users (id int not null auto_increment primary key, name varchar(25));

    create table admins (id int not null auto_incrememnt primary key, userid int, foreign key (userid) references users(id));

    现在你只需将refernce添加到admins当你将是一个管理员用户。此方法允许您在此admins表中使用其他标志和属性(而不是稍后在users表中添加大量列)。

+0

感谢布汉提出了另一种方法 – pouya 2011-12-14 15:09:08

3

而其他的答案是正确的,也有对特定的问题更好的方法,也可以加上空枚举列只有一个单一的情况下,并使其成为一个UNIQUE KEY(创建一个单行表或表的PRIMARY KEY):

mysql> CREATE TABLE only_one_row (
    restriction ENUM('') NOT NULL, 
    single_row_value DATETIME NOT NULL, 
    PRIMARY KEY (restriction) 
); 
Query OK, 0 rows affected (0.00 sec) 

mysql> INSERT INTO only_one_row (single_row_value) VALUES (NOW()); 
Query OK, 1 rows affected (0.00 sec) 

mysql> INSERT INTO only_one_row (single_row_value) VALUES ('2016-01-01'); 
ERROR 1062 (23000): Duplicate entry '' for key 'PRIMARY" 

mysql> SELECT * FROM only_one_row; 
+-------------+---------------------+ 
| restriction | single_row_value | 
+-------------+---------------------+ 
|    | 2016-01-01 00:00:00 | 
+-------------+---------------------+ 

这工作,因为该列永远只能有一个值(ENUM只有一个的情况下,也不可能是NULL),以及UNIQUE(或PRIMARY)键强制实施表中的每一行都必须有一个列的值不同。

这可以以明显的方式进行扩展,以创建只能包含0和任意特定行数之间的表格,达到ENUM的实际限制。 MySQL 5.7中的限制实际上是255个情况,但是到那时,取代TINYINT UNSIGNED列的UNQIUE KEY会更容易。但是,我找不到一种方法来强制执行一个表有 0或N行;这个解决方案只会强制“在0和N之间”,因为MySQL没有工作约束。 (当然,其中N为一个,如在本实施例中,相同的效果。)

:虽然它可能似乎可以使用生成的虚拟列,以避免占用存储的额外的字节对于限制枚举,不幸的是,大多数版本的MySQL和MariaDB在尝试时会抛出各种错误,要么是因为常量值不能用于生成的列,要么是欺骗数据库以允许该值(例如,使用GENERATED ALWAYS AS (LEAST(GREATEST(single_row_value,0),0)) VIRTUAL ),因为存储引擎不喜欢在虚拟生成的列上放置索引。这被记录为自5.7.8以来在MySQL中为InnoDB工作,但在撰写本文时,它绝对不适用于MariaDB 10.1。

编辑补充:这不是万无一失的。 ENUM的“错误”值为零,索引从1开始,因此INSERT INTO only_one_row VALUES (0,...); INSERT INTO only_one_row VALUES (1,...);将成功。但是,这种情况在正常运行中不太可能出现,并且跟踪触发比触发更容易!

相关问题