SQL Ako co najefektivnejsie zmazat strom? rubrika: Databáze: SQL

7 xxar3s
položil/-a 16.9.2016

Mam tabulku Items, obsahujucu stromove polozky. Kazda polozka odkazuje na svojho rodica pomocou ParentId (ten moze byt aj null v pripade korenovej polozky ktora nema rodica), Item.ParentId ma constraint na Item.Id. Zanorenie je neobmedzene.

No a teraz mam problem s mazanim poloziek, ktore obsahuju nejake detske (children) polozky, constraint mi ich pochopitelne nedovoli vymazat a pri constrainte sa neda nastavit delete rule na cascade. Potreboval by som aby sa nejako rekurzivne zmazali vsetky detske polozky az potom ich rodica, rodicia rodicov a takto by sa to opakovalo az kym sa nedostanem na uroven mazanej polozky.

CREATE TABLE [dbo].[Items](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [ParentId] [int] NULL,
    [UserId] [int] NOT NULL,
    [Name] [nvarchar](75) NOT NULL,
    [Note] [nvarchar](max) NOT NULL,
    [Uri] [nvarchar](75) NOT NULL,
    [Guid] [char](36) NOT NULL,
    [Ext] [nvarchar](10) NOT NULL,
    [CreationDate] [datetime2](7) NOT NULL,
    [LastUpdate] [datetime2](7) NOT NULL,
    [Width] [int] NOT NULL CONSTRAINT [DF_Items_Width]  DEFAULT ((-1)),
    [Height] [int] NOT NULL CONSTRAINT [DF_Items_Height]  DEFAULT ((-1)),
    [ThumbWidth] [int] NOT NULL CONSTRAINT [DF_Items_ThumbWidth]  DEFAULT ((-1)),
    [ThumbHeight] [int] NOT NULL CONSTRAINT [DF_Items_ThumbHeight]  DEFAULT ((-1)),
    [Score] [int] NOT NULL CONSTRAINT [DF_Items_Score]  DEFAULT ((-1)),
    [Position] [int] NOT NULL CONSTRAINT [DF_Items_Position]  DEFAULT ((-1)),
    [Type] [int] NOT NULL,
 CONSTRAINT [PK_Items] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
 
GO
 
SET ANSI_PADDING OFF
GO
 
ALTER TABLE [dbo].[Items]  WITH CHECK ADD  CONSTRAINT [FK_Items_Items] FOREIGN KEY([ParentId])
REFERENCES [dbo].[Items] ([Id])
GO
 
ALTER TABLE [dbo].[Items] CHECK CONSTRAINT [FK_Items_Items]
GO
 
ALTER TABLE [dbo].[Items]  WITH CHECK ADD  CONSTRAINT [FK_Items_Users] FOREIGN KEY([UserId])
REFERENCES [dbo].[Users] ([Id])
GO
 
ALTER TABLE [dbo].[Items] CHECK CONSTRAINT [FK_Items_Users]
GO

Komentáře

  • podhy : Sice neporadím, ale je nějaký důvod proč nemáte tedy rovnou daný ten foreign key jako on delete cascade, když to vlastně potřebujete? 16.9.2016
  • Kit : @podhy: Zřejmě používá MyISAM, který to neumí. 16.9.2016
  • xxar3s : pouzivam SQL Server ktory to podporuje, ale nie v tomto konkretnom pripade (constraint na rovnaku tabulku). 16.9.2016
odkaz
7 harrison314
odpověděl/-a 16.9.2016
 
upravil/-a 16.9.2016

Podla [dbo] typujem, ze ide o MS SQL, pre teba je asi najmenej bolestitive to vyriesit trigrom "INSTEAD OF DELETE".
No tu je problem uz v navrhu, mal si pouzit hierarchyid, ktory riesi vsteky problemi okolo stromovej struktury, alebo jeden s paternov pre ukladanie stromovej struktury napr opisane tu, no tam si to uz musis naprogramovat sam.

Komentáře

  • xxar3s : Dik za info, pozriem sa na ten hierarchyid zatial by nemal byt problem to zmenit. 16.9.2016
  • harrison314 : Inak este ma napda, slo by na to vyuzit aj CTE alebo stored proceduru. No ako prve sa odporucam pohrat s hierarchyId. 16.9.2016

Pro zobrazení všech 3 odpovědí se prosím přihlaste:

Rychlé přihlášení přes sociální sítě:

Nebo se přihlaste jménem a heslem:

Zadejte prosím svou e-mailovou adresu.
Zadejte své heslo.