2009-08-30 8 views
25

मैं छोटे छोटे विकी अनुप्रयोग में पृष्ठ संबंधों को संभालने के लिए SQL Server 2008 में नए HierarchyID प्रकार का उपयोग करना चाहता था। हालांकि इसमें एकाधिक रूट नोड्स होने की आवश्यकता होगी क्योंकि प्रत्येक मुख्य लेख/पृष्ठ प्रति खाता रूट नोड होगा।एकाधिक रूट नोड्स के साथ SQL 2008 पदानुक्रमित

मैंने जो पढ़ा है, उसे केवल पदानुक्रमित प्रकार से केवल 1 रूट नोड प्रति कॉलम की अनुमति देता है? और एकाधिक रूट नोड्स को सक्षम करने का कोई तरीका है?

उत्तर

9

हां, आप सही पढ़ रहे हैं - HierarchyID का उपयोग करके केवल एक एकल रूट नोड की अनुमति देता है। वैसे ही यह है और इसके आस-पास कोई रास्ता नहीं है, जहां तक ​​मुझे पता है, एक कृत्रिम नया "über-root" शुरू करने से कम है जो आपको कई अन्य स्तरों के "उप-रूट" की अनुमति देने के अलावा कोई अन्य उद्देश्य नहीं प्रदान करता है। ...

मार्क

+1

यह सही नहीं है। विवरण के लिए मेरा [उत्तर] (http://stackoverflow.com/a/23290250/81595) देखें। –

+1

@ScottMunro: अपने उत्तर पर मेरी टिप्पणी देखें। मेरा मानना ​​है कि मार्क सही है। हालांकि, आप जड़ के बच्चों को रूट-नोड्स – Phil

+0

@ फिल के रूप में उपयोग करने के लिए स्वतंत्र हैं, आपको वास्तव में "उबर-रूट" नोड रखने की आवश्यकता नहीं है। आप '/ 1 /' जैसे नोड के साथ पदानुक्रम शुरू कर सकते हैं और उनके ऊपर मौजूद '/' होने के बिना '/ 2 /' जैसे दूसरे को प्राप्त कर सकते हैं। –

2

आप बस एक, 'गैर दिखाया गया है' जड़ नहीं हो सकता और स्तर 1 से सभी मुख्य लेख है?

29

मैं कुछ परीक्षण कर रहा हूं, और ऐसा लगता है कि आपको रूट पदानुक्रम के साथ रिकॉर्ड की आवश्यकता नहीं है।

उदाहरण के लिए, सामान्य रूप से आप एक रूट नोड (स्तर 1) और कई childen, लेकिन आप रूट नोड को छोड़ सकते हैं हैं, कोई जड़ रिकॉर्ड, सिर्फ रिकॉर्ड स्तर 2 में शुरू होने:

//table schema 
CREATE TABLE [Entity](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Name] [varchar](50) NOT NULL 
    [Hierarchy] [hierarchyid] NOT NULL, 
CONSTRAINT [PK_Entity] PRIMARY KEY CLUSTERED 
(
    [ID] ASC 
) 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

//Insert first 'root', which is technicall a child without a parent 
INSERT INTO [Entity] 
      ([Name] 
      ,[Description] 
      ,[Hierarchy]) 
    VALUES 
      ('Root A' 
      ,hierarchyid::GetRoot().GetDescendant(NULL,NULL)) 


//Create the second 'root' 
INSERT INTO [Entity] 
      ([Name] 
      ,[Hierarchy]) 
    VALUES 
      ('Root B' 
      ,hierarchyid::GetRoot().GetDescendant((select MAX(hierarchy) from entity where hierarchy.GetAncestor(1) = hierarchyid::GetRoot()),NULL)) 

अब यदि आप तालिका से सभी पंक्तियों का चयन करें, आप देखते हैं:

SELECT [ID] 
     ,[Name] 
     ,[Hierarchy], 
     [Hierarchy].ToString() 
    FROM [Entity] 

आईडी         नाम             पदानुक्रम     (कोई स्तंभ नाम)
        रूट एक         0x58                    /1/
        रूट बी         0x68                    /2/

मुझे यकीन है कि इस अभ्यास की सिफारिश की जाएगी अगर नहीं कर रहा हूँ लेकिन धारणात्मक यह आप के रूप में लंबे समय के रूप, आप कई जड़ों की अनुमति देता है पेड़ में दूसरे स्तर को रूट के रूप में देखें

+0

यह बहुत अच्छा है, धन्यवाद। ऐसा लगता है कि आप रूट बनाते हैं या नहीं, वास्तव में महत्वपूर्ण नहीं है, जब तक आप इसे अनदेखा करते हैं, या इसे 'सभी पदानुक्रम' मानते हैं। मुझे उम्मीद है कि यह एक ही बच्चों को कई पदानुक्रमों में शामिल होने की इजाजत देता है, हालांकि मुझे संदेह है कि बच्चों को डुप्लिकेट करना शामिल होगा। – Davos

+1

आपको पेड़ को लागू करने के लिए यहां कोई बाधा नहीं दिखती है - सुनिश्चित करें कि आपके पास ऐसे अनाथ रिकॉर्ड नहीं हैं जो माता-पिता को इंगित करते हैं जो मौजूद नहीं हैं। अधिक जानकारी के लिए मेरा जवाब देखें। –

9

अद्वितीय रूट नोड्स बनाने के लिए मैं क्या करता हूं, बस अपनी तालिका को प्राथमिक वरी को अपने वांछित एंकर रिकॉर्ड पर एक पदानुक्रम के रूप में डाला जाता है, उदाहरण के लिए

ArticleID वाले एक नाटक तालिका को देखते हुए | ArticleID_Parent | पदानुक्रम, आप इस तरह अद्वितीय बनने के लिए सभी "जड़ें" tweak कर सकते हैं;

UPDATE [Article] 
SET Hierarchy=CAST('/'+CAST([ArticleID] as varchar(30))+'/' AS hierarchyid) 
WHERE [ArticleID_Parent]=0 

.. फिर किसी विशेष रूट की "शाखा" प्राप्त करने के लिए;

SELECT * FROM [Article] 
WHERE Article.Hierarchy.IsDescendantOf((SELECT Hierarchy FROM Article WHERE ArticleID=XXXX)) = 1 
+0

सिचबो, जो बहुत अच्छा काम करता है! पारितोषिक के लिए धन्यवाद! – windchaser

6

पदानुक्रमित डेटा प्रकार जिसका उपयोग पदानुक्रम में स्थिति का प्रतिनिधित्व करने के लिए किया जा सकता है। हालांकि यह मूल रूप से पदानुक्रम को लागू नहीं करता है। यह hierarchyid के लिए एमएसडीएन दस्तावेज से निकाला गया है।

यह पदानुक्रमित मूल्यों को उत्पन्न करने और असाइन करने के लिए आवेदन पर निर्भर करता है कि पंक्तियों के बीच वांछित संबंध मूल्यों में परिलक्षित होते हैं।

यह example दिखाता है कि पेड़ को लागू करने के लिए गणना किए गए कॉलम और विदेशी कुंजी का संयोजन कैसे उपयोग किया जा सकता है।

CREATE TABLE Org_T3 
(
    EmployeeId hierarchyid PRIMARY KEY, 
    ParentId AS EmployeeId.GetAncestor(1) PERSISTED 
     REFERENCES Org_T3(EmployeeId), 
    LastChild hierarchyid, 
    EmployeeName nvarchar(50) 
) 
GO 

आपके मामले में, आप अभिकलन स्तंभ सूत्र को संशोधित करेगा ताकि जड़ रिकॉर्ड या तो अशक्त के लिए शायद रिकॉर्ड के असंशोधित hierarchyid या (विदेशी कुंजी अशक्त एसक्यूएल सर्वर में मूल्यों के लिए लागू नहीं कर रहे हैं) (जड़ों होगा अपने माता-पिता) वापस आ जाएंगे।

यह उपर्युक्त उदाहरण का सरलीकृत संस्करण है जो रूट नोड्स को एक शून्य माता-पिता निर्दिष्ट करने की रणनीति के साथ जाता है।

create table Node 
(
    Id hierarchyid primary key, 
    ParentId AS case when Id.GetLevel() = 1 then 
        Null 
       else 
        Id.GetAncestor(1) 
       end PERSISTED REFERENCES Node(Id), 
    check (Id.GetLevel() != 0) 
) 

insert into Node (Id) values ('/1/'); 
insert into Node (Id) values ('/1/1/'); 
insert into Node (Id) values ('/'); --Fails as the roots will be at level 1. 
insert into Node (Id) values ('/2/1/'); --Fails because the parent does not exist. 

select Id.ToString(), ParentId.ToString() from Node; 

उपर्युक्त से केवल वैध आवेषण सफल होते हैं।

ईद ParentId

/1/शून्य

/1/1// 1/

+2

मेरा मानना ​​है कि मार्क तकनीकी-ज्ञान में सही है और आप अर्थपूर्ण अर्थ में हैं।मार्क सही है कि आप केवल एक रूट नोड (/) हो सकता है। उस ने कहा, रूट नोड के बच्चों को "जड़ें" या "उबर-रूट" (जैसे मार्क उन्हें कॉल करता है) को कॉल करने और जड़ों के रूप में उपयोग करने से आपको कुछ भी रोक नहीं रहा है (जैसा आपने किया था)। – Phil

संबंधित मुद्दे