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


180

मुझे इसमें त्रुटि है

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

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

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

16
क्या आपको वास्तव में आपकी (4) बड़ी और अनूठी 4GB की आवश्यकता है? SqlServer इसकी अनुमति नहीं देता है क्योंकि विशिष्टता की जांच करना संभवतः बहुत समय लेने वाला ऑपरेशन हो सकता है।
क्लॉस बाइसकोव पेडरसन

@KlausByskovPedersen कुछ और अधिक शक्तिशाली DBMS जैसे PostgreSQL यह अनुमति देने और इसके बजाय एक डाइजेस्ट को इंडेक्स करने के लिए पर्याप्त स्मार्ट है। लेकिन आपके पास एक बिंदु है।
मथिउ

जवाबों:


244

एक अद्वितीय बाधा प्रति पंक्ति 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 से अधिक वर्ण नहीं हो सकती। यदि आप varcharइसके बजाय nvarchar(जैसे यदि आपको एक से अधिक कोडपृष्ठ से वर्णों को संग्रहीत करने की आवश्यकता नहीं है) स्विच कर सकते हैं, तो यह 900 वर्णों तक बढ़ सकता है।


1
Varchar के लिए, क्या सीमा अभी भी varchar (450) होगी?
स्टीम

9
आप या तो उपयोग करने के लिए जगह है varchar(900)या nvarchar(450)
डैनियल रेनशॉ

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

2
@mrillsy घोषित अधिकतम आकार में ओवरहेड (जो 2 बाइट्स हैं, 4 नहीं) शामिल हैं और ओवरहेड बाइट्स अधिकतम इंडेक्स पंक्ति आकार पर सीमा में शामिल नहीं हैं। Technet.microsoft.com/en-us/library/ms176089(v=sql.100).aspx
डैनियल रेनशॉ

1
@mrills आप उस संदेश को प्राप्त कर रहे हैं क्योंकि आप ID1 intसूचकांक में शामिल हैं। यही कारण है कि int4 बाइट की आवश्यकता है, के लिए 900 बाइट्स के अलावा varchar
डैनियल रेनशॉ

33

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

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

और [dbo]। [चेककी] एक स्केलर फ़ंक्शन है जिसे निम्न रूप में परिभाषित किया गया है:

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

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


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

14

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

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

MSDN पर अधिक पढ़ें


Varchar के लिए, क्या सीमा अभी भी varchar (450) होगी?
भाप में


2

आकार में गीगाबाइट होने के लिए आपकी प्रमुख लंबाई के बारे में klaisbyskov की टिप्पणी, और यह मानते हुए कि आप वास्तव में ऐसा करते हैं, तो मुझे लगता है कि आपके एकमात्र विकल्प हैं:

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

हैशिंग का कहना है कि एक दिन, आपको टक्कर मिल सकती है

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

आप के लिए खत्म है...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.