列表中的项目编号 - 最佳方法?

时间:2009-11-21 11:57:44

标签: sql mysql database-design

我正在创建一组简单的表来存储多个列表。第一个表描述了我的列表,第二个表描述了这些列表中的项目 - 表的定义如下:

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产生一些不良后果 - 因为之前的触发器不会被撤消)。

这是一个很好的方法 - 或者我应该手动在应用程序代码中的事务下执行它,还是应该完全以其他方式执行此操作?

感谢您的帮助 - 我可能会在这里讨论琐事,但我对数据库没有太多经验。

3 个答案:

答案 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,并将该值填入新记录。