Database
 sql >> डेटाबेस >  >> RDS >> Database

अग्रणी वाइल्डकार्ड खोज पर अनुवर्ती #1

मेरी पिछली पोस्ट में, "एक अग्रणी वाइल्डकार्ड के लिए अनुक्रमणिका प्राप्त करने का एक तरीका," मैंने उल्लेख किया है कि आप मेरे द्वारा सुझाए गए अंशों को बनाए रखने से निपटने के लिए ट्रिगर्स की आवश्यकता होगी। कुछ लोगों ने मुझसे यह पूछने के लिए संपर्क किया है कि क्या मैं उन ट्रिगर्स को प्रदर्शित कर सकता हूं।

पिछली पोस्ट से सरल बनाने के लिए, मान लें कि हमारे पास निम्न तालिकाएँ हैं - कंपनियों का एक सेट, और फिर एक CompanyNameFragments तालिका जो कंपनी के नाम के किसी भी विकल्प के विरुद्ध छद्म-वाइल्डकार्ड खोज की अनुमति देती है:

CREATE TABLE dbo.Companies
(
  CompanyID  int CONSTRAINT PK_Companies PRIMARY KEY,
  Name       nvarchar(100) NOT NULL
);
GO
 
CREATE TABLE dbo.CompanyNameFragments
(
  CompanyID int NOT NULL,
  Fragment  nvarchar(100) NOT NULL
);
 
CREATE CLUSTERED INDEX CIX_CNF ON dbo.CompanyNameFragments(Fragment, CompanyID);
पर क्लस्टर इंडेक्स CIX_CNF बनाएं

टुकड़े उत्पन्न करने के लिए इस फ़ंक्शन को देखते हुए (मूल लेख से एकमात्र परिवर्तन यह है कि मैंने @input बढ़ा दिया है 100 वर्णों का समर्थन करने के लिए):

CREATE FUNCTION dbo.CreateStringFragments( @input nvarchar(100) )
RETURNS TABLE WITH SCHEMABINDING
AS
  RETURN 
  (
    WITH x(x) AS 
    (
      SELECT 1 UNION ALL SELECT x+1 FROM x WHERE x < (LEN(@input))
    )
    SELECT Fragment = SUBSTRING(@input, x, LEN(@input)) FROM x
  );
GO

हम एक एकल ट्रिगर बना सकते हैं जो तीनों कार्यों को संभाल सकता है:

CREATE TRIGGER dbo.Company_MaintainFragments
ON dbo.Companies
FOR INSERT, UPDATE, DELETE
AS
BEGIN
  SET NOCOUNT ON;
 
  DELETE f FROM dbo.CompanyNameFragments AS f
    INNER JOIN deleted AS d 
    ON f.CompanyID = d.CompanyID;
 
  INSERT dbo.CompanyNameFragments(CompanyID, Fragment)
    SELECT i.CompanyID, fn.Fragment
    FROM inserted AS i 
    CROSS APPLY dbo.CreateStringFragments(i.Name) AS fn;
END
GO

यह बिना किसी जाँच के काम करता है कि किस प्रकार का ऑपरेशन हुआ क्योंकि:

  • एक अद्यतन या एक DELETE के लिए, DELETE होगा - एक अद्यतन के लिए, हम उन अंशों का मिलान करने की कोशिश नहीं करेंगे जो समान रहेंगे; हम बस उन सभी को उड़ा देंगे, ताकि उन्हें सामूहिक रूप से बदला जा सके। INSERT के लिए, DELETE कथन का कोई प्रभाव नहीं पड़ेगा, क्योंकि deleted में कोई पंक्तियाँ नहीं होंगी ।
  • एक INSERT या एक अद्यतन के लिए, INSERT होगा। DELETE के लिए, INSERT कथन का कोई प्रभाव नहीं पड़ेगा, क्योंकि inserted में कोई पंक्तियाँ नहीं होंगी ।

अब, यह सुनिश्चित करने के लिए कि यह काम करता है, आइए Companies . में कुछ बदलाव करें तालिका और फिर हमारी दो तालिकाओं का निरीक्षण करें।

-- First, let's insert two companies 
-- (table contents after insert shown in figure 1 below)
 
INSERT dbo.Companies(Name) VALUES(N'Banana'), (N'Acme Corp');
 
-- Now, let's update company 2 to 'Orange' 
-- (table contents after update shown in figure 2 below):
 
UPDATE dbo.Companies SET Name = N'Orange' WHERE CompanyID = 2;
 
-- Finally, delete company #1 
-- (table contents after delete shown in figure 3 below):
 
DELETE dbo.Companies WHERE CompanyID = 1;
चित्र 1: प्रारंभिक तालिका सामग्री चित्र 2: अद्यतन के बाद तालिका सामग्री चित्र 3: हटाने के बाद तालिका सामग्री

चेतावनी (संदर्भात्मक अखंडता लोगों के लिए)

ध्यान दें कि यदि आप इन दो तालिकाओं के बीच उचित विदेशी कुंजी सेट करते हैं, तो आपको हटाए जाने को संभालने के लिए ट्रिगर के बजाय एक का उपयोग करना होगा, अन्यथा आपको चिकन और अंडे की समस्या होगी - आप माता-पिता के *बाद* तक प्रतीक्षा नहीं कर सकते बाल पंक्तियों को हटाने के लिए पंक्ति हटा दी जाती है। तो आपको ON DELETE CASCADE सेट करना होगा (जिसे मैं व्यक्तिगत रूप से पसंद नहीं करता), या आपके दो ट्रिगर इस तरह दिखाई देंगे (बाद के ट्रिगर को अभी भी एक अद्यतन के मामले में एक DELETE/INSERT जोड़ी करना होगा):

CREATE TRIGGER dbo.Company_DeleteFragments
ON dbo.Companies
INSTEAD OF DELETE
AS
BEGIN
  SET NOCOUNT ON;
 
  DELETE f FROM dbo.CompanyNameFragments AS f
    INNER JOIN deleted AS d
    ON f.CompanyID = d.CompanyID;
 
  DELETE c FROM dbo.Companies AS c
    INNER JOIN deleted AS d
    ON c.CompanyID = d.CompanyID;
END
GO
 
CREATE TRIGGER dbo.Company_MaintainFragments
ON dbo.Companies
FOR INSERT, UPDATE
AS
BEGIN
  SET NOCOUNT ON;
 
  DELETE f FROM dbo.CompanyNameFragments AS f
    INNER JOIN deleted AS d
    ON f.CompanyID = d.CompanyID;
 
  INSERT dbo.CompanyNameFragments(CompanyID, Fragment)
    SELECT i.CompanyID, fn.Fragment
    FROM inserted AS i
    CROSS APPLY dbo.CreateStringFragments(i.Name) AS fn;
END
GO

सारांश

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

अपनी अगली पोस्ट में, मैं दिखाऊंगा कि इस पसंद के प्रभाव को कैसे देखा जाए:आप क्वेरी समय पर प्रदर्शन बचत के खिलाफ टुकड़ों को बनाए रखने की संसाधन लागत की तुलना करने के लिए आसानी से प्रतिनिधि वर्कलोड सेट कर सकते हैं। मैं अलग-अलग स्ट्रिंग लंबाई के साथ-साथ अलग-अलग वर्कलोड बैलेंस (ज्यादातर पढ़ा बनाम अधिकतर लिखता हूं) को देखूंगा और मीठे धब्बे और खतरे के क्षेत्रों को खोजने का प्रयास करूंगा।


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Windows Azure VM प्रदर्शन की तुलना करना, भाग 2

  2. पार्स पैरामीटर डिफ़ॉल्ट मान PowerShell का उपयोग कर - भाग 3

  3. आरडीएस समाधान में बड़ी तालिका में परिवर्तन तालिका पूर्ण त्रुटि के लिए

  4. डेटा गवर्नेंस के लिए मानवीय दृष्टिकोण अपनाएं

  5. स्केलग्रिड ने प्रबंधित डेटाबेस होस्टिंग के लिए Google क्लाउड प्लेटफ़ॉर्म (GCP) समर्थन लॉन्च किया