代码之家  ›  专栏  ›  技术社区  ›  Álvaro García

如何在多对多自关系表中增加行并保持一致性?

  •  0
  • Álvaro García  · 技术社区  · 5 年前

    我有一张多对多自我关系的桌子。我有两张桌子。

    TableA
    {
        IDTableA;
        Data;
    }
    
    Realtionships
    {
        IDTableA;
        IDTableARelated;
    }
    

    我现在想知道,对于TableA中的一行,TableA中的哪些行与该行相关。

    我有两个选项,只向Relationsips表添加一行,例如(1,2),在本例中,2与1相关,但2如何与1相关,1也与2相关。但这有一个如何避免重复的问题。例如,如果一个进程尝试添加(1,2),而另一个进程尝试添加(2,1),我如何避免这种重复?

    所以第二个选择是始终添加两行(1,2)和(2,1)。但我不知道如何确保我总是有两排。我在想这两个问题:

    Begin tran
    insert into Relations(IDTableA, IDTableARelated) VALUES(1,2);
    insert into Relations(IDTableA, IDTableARelated) VALUES(2,1);
    commint
    
    
    Begin tran
    delete TableAB where IDTableA = 1 and IDTableARelated = 2;
    delete TableAB where IDTableA = 2 and IDTableARelated = 1;
    commit
    

    但是在我的测试中,我可以得到结果,在最后我只有一行。例如,如果行(1,2)存在,则可能发生以下情况:

    • 第一个进程尝试添加行(1,2)。
    • 第二个进程尝试删除行(2,1);
    • 第一个过程尝试添加(2,1);
    • 第二个过程尝试删除(1,2);

    最后的结果是我只有行(2,1),所以它没有连贯性,我应该也有行(1,2)。

    实际上,在我的例子中,我可以选择选项一或选项二,但是我想知道tsql是否有某种方法来确保数据的一致性,如果是选项1,为了避免重复,如果是第二个解决方案,请确保始终保留这两行。

    谢谢。

    USE [TestRelacionN-N]
    GO
    /****** Object:  Table [dbo].[TablaA]    Script Date: 26/05/2019 11:07:52 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[TablaA](
        [IDTablaA] [bigint] IDENTITY(1,1) NOT NULL,
        [Dato] [varchar](50) NULL,
     CONSTRAINT [PK_TablaA] PRIMARY KEY CLUSTERED 
    (
        [IDTablaA] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    /****** Object:  Table [dbo].[TableAWithTableA]    Script Date: 26/05/2019 11:07:52 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    CREATE TABLE [dbo].[TableAWithTableA](
        [IDTableA] [bigint] NOT NULL,
        [IDTableARelated] [bigint] NOT NULL,
     CONSTRAINT [PK_TableAWithTableA] PRIMARY KEY CLUSTERED 
    (
        [IDTableA] ASC,
        [IDTableARelated] ASC
    )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
    ) ON [PRIMARY]
    GO
    SET IDENTITY_INSERT [dbo].[TablaA] ON 
    
    INSERT [dbo].[TablaA] ([IDTablaA], [Dato]) VALUES (1, N'Dato01')
    INSERT [dbo].[TablaA] ([IDTablaA], [Dato]) VALUES (2, N'Dato02')
    INSERT [dbo].[TablaA] ([IDTablaA], [Dato]) VALUES (3, N'Dato03')
    SET IDENTITY_INSERT [dbo].[TablaA] OFF
    INSERT [dbo].[TableAWithTableA] ([IDTableA], [IDTableARelated]) VALUES (1, 2)
    
    0 回复  |  直到 5 年前