包含可以安排的记录的表格

时间:2011-04-01 13:55:03

标签: mysql sql database-design


如何制作一个具有相互排序的行的表格,并且可以重新排列:
例如:

Rows:idappearance name
Records
 (1,"john"),(2,"mike")

现在,我想在它们之间插入“Avi”:
不必担心重新安排它们

(1,"john"),(2,"Avi"),(3,"mike")
  • 此表可以包含外键 另一张桌子(如部门..)。
  • idappearance是我想要的外观顺序 设置,不需要PK。
  • 它需要处理大约50K的名称,因此O(n)不是最佳解决方案。

3 个答案:

答案 0 :(得分:2)

简单的解决方案是在记录之间存在合理的数值差距。换句话说;

(10000,“John”),(20000,“mike”)

(10000, “约翰”),(15000, “AVI”),(20000, “迈克”)

(10000, “约翰”),(12500, “汤姆”),(15000, “AVI”),(20000, “迈克”)

等。

记录之间的差距应根据您的数据域确定

答案 1 :(得分:1)

您可以在插入时触发。我不使用MySQL,但这里是sql-server的代码......

基本上,在插入时,触发器会增加所有行的appearanceId,其中的appearanceId等于或大于新的外观ID。

CREATE Table OrderedTable
(
    id  int IDENTITY,
    name varchar(50),
    appearanceOrder int
)
GO

CREATE TRIGGER dbo.MyTrigger
   ON  dbo.OrderedTable
   AFTER INSERT
AS 
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    UPDATE OrderedTable SET
        AppearanceOrder = AppearanceOrder + 1
    WHERE   AppearanceOrder >= (
        SELECT TOP 1 AppearanceOrder 
        FROM inserted )
    AND id NOT IN (
        SELECT id
        FROM inserted )

END
GO

INSERT INTO OrderedTable VALUES ('Alice', 1)
INSERT INTO OrderedTable VALUES ('Bob', 1)
INSERT INTO OrderedTable VALUES ('Charlie', 1)
INSERT INTO OrderedTable VALUES ('David', 1)

这让David,Charlie,Bob,Alice如预期的那样回归。

SELECT  *
FROM    OrderedTable
ORDER BY    AppearanceOrder

请注意,我尚未完全测试此实现。一个问题是,如果删除项目,或者插入故意插入当前范围之外,它将在AppearanceOrder中留下漏洞。如果这些问题重要,它们将作为练习留给读者; - )

答案 2 :(得分:0)

如果外观顺序是双精度浮点数,则可以使用单个插入在任意两个相邻名称之间插入任何名称。如果你从这样的表开始:

create table test (
    person_id integer primary key,
    person_name varchar(10) not null,
    appearance_order double precision not null unique
);

insert into test values (100, 'John', 11);
insert into test values (23, 'Mike', 12);

只需

即可在它们之间插入Avi
insert into test values (3, 'Avi', 11.5);

按“appearance_order”列排序。

select * from test order by appearance_order
100   John   11
3     Avi    11.5
23    Mike   12

通过

在John和Avi之间插入Eva
insert into test values (31, 'Eva', 11.25);

select * from test order by appearance_order
100   John   11
31    Eva    11.25
3     Avi    11.5
23    Mike   12

执行需要将标识与排序顺序分开。这意味着使用一列作为id号(并作为外键引用的目标),另一列作为外观顺序。但是,根据您的应用程序,您可能不需要对appearance_order进行唯一约束。