在我的MariaDB数据库中,我有三个表Users
,Workers
和Admins
,其中Users
表具有列ID
作为主键。 Workers
和Admins
使用Users.ID
作为外键(和主键)。用户可以是Workers或Admins,不能两者都是。如何使用Users.ID
来确定他们是工作者还是管理员?
我已经尝试过此功能:
CREATE FUNCTION workeroradmin(id INT)
RETURNS VARCHAR(20)
BEGIN
DECLARE type VARCHAR(20)
IF (SELECT COUNT(*) FROM Workers WHERE ID = id) = 1
THEN
SET type='Worker'
ELSEIF (SELECT COUNT(*) FROM Admins WHERE ID = id) = 1
THEN
SET type='Admin'
RETURN type;
END;
但这只会给我SQL语法错误。函数是到这里的方法还是简单的IF子句就足够了?
答案 0 :(得分:0)
您确定一个用户不能同时成为Worker和Admin吗?
我会改成这样:
SELECT
Users.Id
, IF(Workers.Id IS NOT NULL, 1, 0) AS IsWorker
, IF(Admins.Id IS NOT NULL, 1, 0) AS IsAdmin
FROM
Users
LEFT JOIN Workers ON (Workers.Id = Users.Id)
LEFT JOIN Admins ON (Admins.Id = Users.Id)
WHERE
...
;
您可以使用子查询代替LEFT JOIN进行相同的操作。
如果您确实想使用自己的方式,则可以执行以下操作:
DELIMITER $$
CREATE FUNCTION `workeroradmin`(`_id` INT)
RETURNS varchar(20)
LANGUAGE SQL
BEGIN
IF((SELECT `Id` FROM `Workers` WHERE `Id` = _id) IS NOT NULL) THEN
SET @result = 'Worker';
ELSEIF((SELECT `Id` FROM `Admins` WHERE `Id` = _id) IS NOT NULL) THEN
SET @result = 'Admin';
END IF;
RETURN @result;
END$$
DELIMITER ;
我不会只使用COUNT来检查是否存在,因为这不是最优的,Id也会如此。
答案 1 :(得分:0)
我不知道此解决方案是否对您而言过于矫kill过正,但您实际上可以强制用户将其作为工作人员“异或”管理员。此解决方案从MariaDB 10.2.1开始有效。
您可以使用复合主键和CHECK
约束(实际上在MariaDB 10.2.1和更高版本中有效)。
例如:
create table users (
id int not null,
type int not null check (type in (1, 2)),
name varchar(20),
primary key (id, type)
);
create table workers (
id int not null,
type int not null check (type = 1),
position varchar(20),
primary key (id, type),
foreign key (id, type) references users (id, type)
);
create table admins (
id int not null,
type int not null check (type = 2),
server varchar(20),
primary key (id, type),
foreign key (id, type) references users (id, type)
);
insert into users (id, type, name) values (100, 1, 'Anne'); -- worker
insert into workers (id, type, position) values (100, 1, 'Manager');
insert into users (id, type, name) values (105, 2, 'Tom'); -- admin
insert into admins (id, type, server) values (105, 2, 'server1');
insert into workers (id, type, position) values (105, 2, 'Programmer'); -- fails!
看到了吗?最后一次插入失败,因此Tom不能同时是管理员和工作者,并且这是在数据库级别而不是您的代码上强制执行的。
然后,您如何知道它是管理员还是工人?只需查看表type
中的列users
。更简单,更便宜。
干杯!