2010-05-19 8 views
123

मुझेएक प्रकार का है जो किसी इंडेक्स में एक प्रमुख कॉलम के रूप में उपयोग के लिए अमान्य है

Column 'key' in table 'misc_info' is of a type that is invalid for use as a key column in an index. 

पर एक त्रुटि है जहां कुंजी एक nvarchar (अधिकतम) है। एक त्वरित गूगल found this। हालांकि यह समझ में नहीं आता कि समाधान क्या है। मैं शब्दकोश की तरह कुछ कैसे बना सकता हूं जहां कुंजी और मान दोनों स्ट्रिंग हैं और स्पष्ट रूप से कुंजी अद्वितीय होना चाहिए और एकल है। मेरा एसक्यूएल कथन

create table [misc_info] (
[id] INTEGER PRIMARY KEY IDENTITY NOT NULL, 
[key] nvarchar(max) UNIQUE NOT NULL, 
[value] nvarchar(max) NOT NULL); 
था
+12

क्या आपको वास्तव में 4 जीबी बड़ी और अद्वितीय होने की संभावना है? SqlServer इसकी अनुमति नहीं देता है क्योंकि विशिष्टता की जांच संभवतः ** ** ** ** उपभोग करने वाला ऑपरेशन हो सकती है। –

उत्तर

4

एक समाधान nvarchar(20) के रूप में अपने प्रमुख घोषित करने के लिए होता था।

9

एकमात्र समाधान आपके अद्वितीय सूचकांक में कम डेटा का उपयोग करना है। आपकी कुंजी सबसे ज्यादा एनवीएआरएआरएआर (450) हो सकती है।

"SQL सर्वर सभी इंडेक्स कुंजी कॉलम के अधिकतम आकार के लिए 900-बाइट सीमा बनाए रखता है।"

MSDN

+0

वर्कर के लिए, क्या सीमा अभी भी वर्चर (450) होगी? – Steam

183

एक अद्वितीय बाधा पर और अधिक पढ़ें पंक्ति प्रति 8000 बाइट नहीं किया जा सकता और उसके बाद ही यहां तक ​​कि पहले 900 बाइट्स का उपयोग करेगा तो अपनी चाबी के लिए सबसे सुरक्षित अधिकतम आकार होगा:

create table [misc_info] 
( 
    [id] INTEGER PRIMARY KEY IDENTITY NOT NULL, 
    [key] nvarchar(450) UNIQUE NOT NULL, 
    [value] nvarchar(max) NOT NULL 
) 

यानी 450 से अधिक वर्ण नहीं हो सकते हैं। यदि nvarchar के बजाय वर्चर पर स्विच कर सकते हैं (उदा। यदि आपको एक से अधिक कोडपेज से वर्णों को स्टोर करने की आवश्यकता नहीं है) तो यह 900 वर्णों तक बढ़ सकता है।

+0

वर्कर के लिए, क्या सीमा अभी भी वर्चर (450) होगी? – Steam

+5

आपके पास 'वर्कर (900) 'या' nvarchar (450) 'का उपयोग करने के लिए स्थान है। –

+0

मेरी समझ यह है कि एक वर्चर आइटम की लंबाई निर्धारित करने के लिए 4 बाइट लेगा, जिसका अर्थ है कि वास्तविक सीमा को वर्चर (896) होना चाहिए। क्या ये सही है? – mrmillsy

2

अपने कुंजी लंबाई आकार में गीगाबाइट होने के लिए की आवश्यकता होगी, और यह सोचते हैं कि आप वास्तव में इस की जरूरत के बारे में klaisbyskov की टिप्पणी ध्यान देने योग्य बात है, तो मुझे लगता है कि अपने ही विकल्प हैं:

  1. कुंजी मान के हैश का उपयोग
    • nchar (40) पर एक स्तंभ बनाएँ (एक SHA1 हैश के लिए, उदाहरण के लिए),
    • हैश स्तंभ पर एक अद्वितीय कुंजी डाल दिया।
    • जब बचत या रिकॉर्ड
  2. डालने या अद्यतन पर एक मौजूदा मैच के लिए तालिका क्वेरी करने के लिए चलाता है अद्यतन करने हैश उत्पन्न करते हैं।

हैशिंग चेतावनी है कि एक दिन, आप एक टक्कर मिल सकता है के साथ आता है।

ट्रिगर पूरी तालिका को स्कैन करेंगे।

आप के लिए अधिक ...

19

एसक्यूएल सर्वर (ऊपर तक 2008 R2) कि varchar (max) और nvarchar (मैक्स) (और पाठ, ntext की तरह कई अन्य प्रकार के) में एक सीमा नहीं है नहीं किया जा सकता सूचकांक में आपके पास 2 विकल्प हैं:
1. कुंजी फ़ील्ड पर सीमित आकार सेट करें। nvarchar (100)
2. एक चेक बाधा बनाएँ जो तालिका में सभी कुंजी के साथ मान की तुलना करता है। शर्त है:

([dbo].[CheckKey]([key])=(1)) 

और [डीबीओ]।[CheckKey] एक अदिश समारोह के रूप में परिभाषित किया गया है:

CREATE FUNCTION [dbo].[CheckKey] 
(
    @key nvarchar(max) 
) 
RETURNS bit 
AS 
BEGIN 
    declare @res bit 
    if exists(select * from key_value where [key] = @key) 
     set @res = 0 
    else 
     set @res = 1 

    return @res 
END 

लेकिन ध्यान दें कि एक देशी सूचकांक इसलिए जब तक आप वास्तव में लंबाई निर्दिष्ट नहीं कर सकते एक चेक बाधा की तुलना में अधिक performant है, जांच बाधा उपयोग नहीं करते।

+0

चालाक - ट्रिगर्स की तुलना में अच्छा, मुझे लगता है। –

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

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