क्या मैं विभाजन कुंजी को अपडेट करके विभाजन के बीच पंक्तियों को स्थानांतरित कर सकता हूं?


17

मुझे लगता है कि यह एक काफी सरल प्रश्न होगा, लेकिन मुझे वास्तव में इसके लिए उत्तर खोजने में एक कठिन समय मिला है।

प्रश्न: क्या आप किसी विभाजन तालिका के भीतर डेटा की पंक्तियों को एक विभाजन से दूसरे में विभाजित कर सकते हैं बस विभाजन कॉलम को अपडेट करके ताकि यह विभाजन सीमा को पार कर जाए?

उदाहरण के लिए, यदि मेरे पास एक तालिका है जिसमें एक विभाजन कुंजी है:

CREATE TABLE SampleTable
(
    SampleID INT PRIMARY KEY,
    SampleResults VARCHAR(100) NOT NULL,
)

प्राथमिक कुंजी के लिए मैप करने वाले विभाजन फ़ंक्शन के साथ:

CREATE PARTITION FUNCTION MyPartitionFunc (INT) AS
RANGE LEFT FOR VALUES (10000, 20000);

क्या मैं सैंपलिड को 1 से (कहते हैं) 500,000 में बदलकर पहले विभाजन से तीसरे विभाजन तक एक पंक्ति ले जा सकता हूं?

नोट: मैं इसे sql सर्वर 2005 और 2008 दोनों के रूप में टैग कर रहा हूं, क्योंकि वे दोनों विभाजन का समर्थन करते हैं। क्या वे इसे अलग तरीके से संभालते हैं?

जवाबों:


14

मेरे पास परीक्षण करने के लिए 2005 का सर्वर नहीं है। 2008, हालांकि, उम्मीद के मुताबिक इसे संभालता है:

USE [Test]
GO
CREATE TABLE [IDRanges](
    [ID] [int] NOT NULL
)
GO

CREATE PARTITION FUNCTION IDRange1 (int)
AS RANGE LEFT FOR VALUES (10) ;
GO
--Add one record to each partition
INSERT INTO IDRanges ([ID]) VALUES (17)
INSERT INTO IDRanges ([ID]) VALUES (7)
GO
--Verify records in partition
SELECT $PARTITION.IDRange1([ID]) AS Partition, COUNT(*) AS [COUNT] 
FROM IDRanges
GROUP BY $PARTITION.IDRange1([ID]) 
ORDER BY Partition ;
GO
--Move row between partitions
UPDATE IDRanges
SET [ID] = 8 WHERE [ID] = 17
GO
--Verify records in partition
SELECT $PARTITION.IDRange1([ID]) AS Partition, COUNT(*) AS [COUNT] 
FROM IDRanges
GROUP BY $PARTITION.IDRange1([ID]) 
ORDER BY Partition ;

आपको अपडेट से पहले प्रत्येक विभाजन में एक रिकॉर्ड देखना चाहिए, और बाद में पहले विभाजन में दोनों रिकॉर्ड।


1
कि जवाब के एक अच्छी तरह से किया टुकड़ा है!
मैरियन

यह SQL Server 2005 में वर्णित के रूप में अच्छी तरह से कार्यान्वित
बेन Brocka

-1 यह परिदृश्य का परीक्षण नहीं करता है। $PARTITIONकेवल इनपुट के आधार पर विभाजन संख्या की गणना करता है; यह वास्तव में परीक्षण नहीं करता है कि पंक्ति शारीरिक रूप से कहां रहती है।
जॉन सिगेल

9

इसका परीक्षण करने के लिए, प्रयोग को वास्तव में तालिका को विभाजित करने की आवश्यकता है। Http://www.kodyaz.com/articles/how-to-partition-table-non-partitioned-table-sql-server-2008.aspx देखें

पार्टीशनिंग फंक्शन को छोड़ना आपको बताता है कि पार्टिशनिंग फंक्शन क्या कहता है। यह नहीं कहता कि डेटा कहाँ संग्रहीत है। आप एक विभाजन फ़ंक्शन सेट कर सकते हैं और इसे वास्तव में एक टेबल को विभाजित किए बिना चला सकते हैं, जैसा कि पहले ही यहां प्रदर्शित किया गया है।

तालिका को विभाजित करने के लिए, आपको फ़ाइल समूह और एक विभाजन योजना भी बनानी होगी जो विभाजन के कार्य का उपयोग करते हुए फ़ाइल समूहों के लिए फ़ंक्शन परिणाम असाइन करें। फिर आपको उस पार्टीशन स्कीम का उपयोग करने वाली तालिका पर एक क्लस्टर्ड की डालनी होगी।

विभाजन को सेट करें

मैं कमांड लाइन एसक्यूएल में कोई विशेषज्ञ नहीं हूं। मैंने फ़ाइल समूहों pfg1 (pf1 फ़ाइल के साथ) और pfg2 (pf2 फ़ाइल के साथ) सेट करने के लिए SSMS इंटरफ़ेस का उपयोग किया। तब मैंने विभाजन कार्य और योजना की घोषणा की:

CREATE PARTITION FUNCTION IDRange1 (int)
AS RANGE LEFT FOR VALUES (10) ;
GO

CREATE PARTITION SCHEME ps_IDRange1
AS PARTITION IDRange1
TO (pfg1, pfg2)
GO

तालिका और क्लस्टर इंडेक्स बनाएं

CREATE TABLE [IDRanges](
    [ID] [int] NOT NULL
)
GO

CREATE CLUSTERED INDEX PK_IDRanges
ON dbo.IDRanges(id) ON ps_IDRange1 (ID)
GO

ऐसा करने के बाद, जब आप sys.partitions (मेरे पास 2005 है) को क्वेरी करते हैं, तो आप देखते हैं कि तालिका में अब तालिका के लिए केवल एक के बजाय दो विभाजन हैं। यह इंगित करता है कि हमने इस तालिका के लिए विभाजन को पूरी तरह से लागू कर दिया है।

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id index_id विभाजन_नंबर hows_id पंक्तियाँ
-------------------- ----------- ----------- -------- -------- -------------------- --------------------
72057597780295680 770674389 1 1 72057597780295680 0
72057597780361216 770674389 1 2 72057597780361216 0

अब जबकि हमारे पास दो विभाजन हैं (प्रत्येक के लिए एक पंक्ति गणना के साथ), हम एक प्रयोग कर सकते हैं।

पंक्तियाँ डालें

INSERT INTO IDRanges ([ID]) VALUES (17)
INSERT INTO IDRanges ([ID]) VALUES (7)

क्या हुआ है यह देखने के लिए sys.partitions की जाँच करें।

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id index_id विभाजन_नंबर hows_id पंक्तियाँ
-------------------- ----------- ----------- -------- -------- -------------------- --------------------
72057597780295680 770674389 1 1 72057597780295680 1
72057597780361216 770674389 1 2 72057597780361216 1

हां। प्रत्येक विभाजन में एक पंक्ति।

एक पंक्ति ले जाएँ।

UPDATE IDRanges
SET [ID] = 8 WHERE [ID] = 17

विभाजन की जाँच करें

select * from sys.partitions where object_id = object_id('IDRanges')
partition_id object_id index_id विभाजन_नंबर hows_id पंक्तियाँ
-------------------- ----------- ----------- -------- -------- -------------------- --------------------
72057597780295680 770674389 1 1 72057597780295680 2
72057597780361216 770674389 1 2 72057597780361216 0

पहले विभाजन में अब 1 के बजाय दो पंक्तियाँ हैं, और दूसरे विभाजन में दो के बजाय शून्य पंक्तियाँ हैं।

मुझे लगता है कि यह पुष्टि करता है कि विभाजन तालिका में संकुल कुंजी को संशोधित करने के परिणामस्वरूप पंक्ति स्वचालित रूप से स्थानांतरित हो गई थी।


1
इस प्रश्न के पहले उत्तर के लिए +1 जो वास्तव में परिदृश्य का परीक्षण करता है। DBA.SE में आपका स्वागत है!
जॉन सेबेल

-1 क्या आप कृपया मुझे MSDN दस्तावेज़ों की ओर संकेत कर सकते हैं जो एक तालिका को 'पूरी तरह से' विभाजित करने के लिए आपकी आवश्यकताओं का समर्थन करते हैं? विशेष रूप से अलग फ़ाइल-समूहों और एक संकुल सूचकांक के लिए आवश्यकता?
केनेथ

-2

मुझे नहीं लगता कि यह उत्तर सही है। जब आप मूल्य का उपयोग करते हैं

 $PARTITION.IDRange1([ID]) AS Partition

आप केवल यह बता रहे हैं कि विभाजन क्या होना चाहिए, न कि जहां रिकॉर्ड वर्तमान में है।

आपको उपयोग करना चाहिए:

select * from sys.partitions where object_id = object_id('IDRanges')

2005 के एसक्यूएल पर मेरे परीक्षणों में मूल्य में परिवर्तन होता है लेकिन रिकॉर्ड उसी विभाजन में रहता है। यह संभवतः आँकड़ों और ऑप्टिमाइज़र के साथ गड़बड़ करेगा क्योंकि यह एक बहु थ्रेडेड मोड में चलेगा, जिससे एक विशिष्ट सीमा में विभाजन की उम्मीद होगी। यह भी पूरी तरह से गलत होगा जब यह केवल संबंधित विभाजन को क्वेरी करने के लिए विभाजन उन्मूलन का उपयोग करने का प्रयास करता है। मुझे लगता है कि आपको उन्हें हटाने के लिए प्रत्येक रिकॉर्ड को हटाना और फिर से सम्मिलित करना होगा।


2
$partition यहाँ पर खोज करने से पता चलता है कि स्वीकृत उत्तर सही है। आप कैसे पुष्टि कर रहे हैं कि रिकॉर्ड अपडेट होने के बाद उसी पार्टीशन में रहता है?
निक चामास

पहला बिंदु सच है, लेकिन यह निष्कर्ष कि पंक्ति नहीं चलती है, झूठी है - संभवतः परीक्षण के साथ कुछ गड़बड़ है जो चलाया गया था।
जॉन सीगेल
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.