我正在创建一组简单的表来存储多个列表。第一个表描述了我的列表,第二个表描述了这些列表中的项目 - 表的定义如下:
CREATE TABLE `listman_list` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`title` varchar(100) NOT NULL,
`description` varchar(1000) NOT NULL,
`id_counter` integer UNSIGNED NOT NULL
)
CREATE TABLE `listman_listitem` (
`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
`number` integer UNSIGNED NOT NULL,
`title` varchar(100) NOT NULL,
`description` varchar(10000) NOT NULL,
`list_id` integer NOT NULL,
)
每个listitem
都有一个数字字段,用于描述其相对于列表的唯一编号。这是为了使列表项能够为列表唯一编号(但不是全局编号,这个编号与其主键不同)。例如。所以我可以列出一个项目1,2,3和列表两个项目1,2,3等。
现在,对第二个表中的项目进行编号的最佳方法是什么?目前我有一对触发器:
CREATE TRIGGER set_listitem_number
BEFORE INSERT ON listman_listitem
FOR EACH ROW
SET NEW.number = (SELECT DISTINCT id_counter FROM listman_list id=NEW.list_id);
CREATE TRIGGER inc_listcounter
AFTER INSERT ON listman_listitem
FOR EACH ROW
UPDATE listman_list SET id_counter = id_counter+1 WHERE id=NEW.list_id;
第一个在插入之前设置列表表中的列表项编号,而第二个在成功插入后在列表中递增计数器(我听说在插入之前修改其他表如果事务失败,则会对MySQL产生一些不良后果 - 因为之前的触发器不会被撤消)。
这是一个很好的方法 - 或者我应该手动在应用程序代码中的事务下执行它,还是应该完全以其他方式执行此操作?
感谢您的帮助 - 我可能会在这里讨论琐事,但我对数据库没有太多经验。
答案 0 :(得分:1)
我不理解您在触发器中的查询。您不想找到现有的最高数字(在列表中)并将其递增一个吗?我不知道MySQL语法的来龙去脉,但这并不是你正在做的事情。我期望在这个查询中看到Max()或Count()。
除此之外,我认为需要在最后一个位置插入新项目,这意味着需要使用所有项目。触发器无法执行此操作,因此我建议您在应用程序中处理此问题。
之前讨论了维护排序顺序的问题,例如here
答案 1 :(得分:0)
ID列有什么问题 - 服务器负责增加这些并使它们成为唯一。
答案 2 :(得分:0)
摆脱id_counter列,只是担心保持同步的另一条信息。摆脱触发器,并通过存储过程执行所有插入。我正在粘贴一些用T-SQL编写的代码,所以它可能需要在MySQL中稍微改变一下语法,但它传达了一般的想法。
CREATE PROC insert_listItem(@list_id int, @title varchar(100), @description varchar(1000))
AS
INSERT listman_listitem(number, title, description, list_id)
SELECT COALESCE(MAX(number), 0) + 1,
@title,
@description,
@list_id
FROM
listman_listitem
WHERE
list_id = @list_id
这将找到给定list_id存在的最大数字(如果不存在则为零),将其递增1,并将该值填入新记录。