Her zaman nvarchar (MAX) kullanmanın herhangi bir dezavantajı var mı?


342

SQL Server 2005'te, açıkça bir uzunluk belirtmek yerine tüm karakter alanlarını nvarchar (MAX) yapmanın herhangi bir dezavantajı var mı, örneğin nvarchar (255)? (Alan uzunluğunu veritabanı düzeyinde sınırlayamayacağınız aşikar olanın dışında)


1
Birisinin neden 8000+ karakterden oluşan bir ad girmesine izin vermek istediğinizi anlamıyorum.
DForck42

2
Aynı mantık programlama dillerine de uygulanabilir. Tüm verilerimiz için neden eski VB6 varyantına geri dönmeyelim? Birden fazla yerde kontrol ve bakiye bulundurmanın mutlaka kötü olduğunu düşünmüyorum.
Matt Spradley

1
Şunu

10
Güncellemeniz bu soruya kendi cevabı olmalıdır.
Johann

soru-cevap, orijinal yazar bunu yapmadığı için doğru cevaba taşındı. stackoverflow.com/a/35177895/10245 Ben 7 yıl yeterli zaman rakam :-)
Tim Abell

Yanıtlar:


153

Aynı soru MSDN Forumları'nda da soruldu:

Orijinal gönderiden (daha fazla bilgi var):

Verileri bir VARCHAR (N) sütununa depoladığınızda, değerler fiziksel olarak aynı şekilde saklanır. Ancak bir VARCHAR (MAX) sütununa kaydettiğinizde, ekranın arkasında veriler METİN değeri olarak işlenir. Bu nedenle, bir VARCHAR (MAX) değeriyle uğraşırken bazı ek işlemlere ihtiyaç vardır. (yalnızca boyut 8000'i aşarsa)

VARCHAR (MAX) veya NVARCHAR (MAX) 'büyük değer türü' olarak kabul edilir. Büyük değer türleri genellikle 'sıra dışı' olarak depolanır. Bu, veri satırının "büyük değer" in depolandığı başka bir konuma işaretçi olacağı anlamına gelir ...


2
Soru şu olmalı, N / VARCHAR (MAX) ve N / TEXT kullanımı arasında bir fark var mı?
Lisanssız

18
Doğru hatırlıyorsam, sadece boyut 8k'yi aşarsa sıra dışında saklanmazlar mı?
Sam Schutte

79
Cevabı "hayır, kullanmanın hiçbir dezavantajı yok" olarak okudum, N/VARCHAR(MAX)çünkü "sadece 8000'i aştığında ek işleme var". Böylece, maliyeti sadece gerektiğinde alırsınız ve veritabanınız daha az kısıtlayıcıdır . Bunu yanlış mı okuyorum? Eğer hemen her zaman isteyeyim gibi görünüyor N/VARCHAR(MAX)ziyade N/VARCHAR(1-8000)...
Kent Boogaart

1
Yukarıdaki ölü bağlantı
MSDN'deki

68
Ne yazık ki bu cevabın bir takım problemleri var. Bu değer de dahil olmak üzere may daha faktörler dayalı sıranın dışına itilmiş olur, sınır 8k sihirli numarası gibi görünüyor yapar doğru değildir sp_tableoptions: msdn.microsoft.com/en-us/library/ms173530.aspx . VARCHAR (255) türleri de sıra dışına itilebilir, belirtilen 'genel gider' MAX ve 255 için tam olarak aynı olabilir. MAX türlerini TEXT türleriyle, farklı olduklarında (manipüle etmek için tamamen farklı API, farklı depolama vb). Gerçek farklardan bahsetmez: endeks yok, MAX türlerinde çevrimiçi işlem yok
Remus Rusanu

50

Bu adil bir soru ve bariz olandan ayrı olarak ifade etti…

Dezavantajları şunları içerebilir:

Performans sonuçları Sorgu iyileştirici, en etkili uygulama planını belirlemek için alan boyutunu kullanır

"1. Veritabanındaki alan tahsisi uzar ve veritabanının sayfaları esnektir. Bu nedenle, güncellemeyi kullanarak alana bilgi eklerken, yeni veriler bir öncekinden daha uzunsa, bir işaretçi oluşturmak zorunda kalacaktır. Bu veritabanı dosyaları parçalanmak = dizinden silmek, güncellemek ve eklemek için neredeyse her şeyde daha düşük performans. " http://sqlblogcasts.com/blogs/simons/archive/2006/02/28/Why-use-anything-but-varchar_2800_max_2900_.aspx

Entegrasyon sonuçları - diğer sistemlerin veritabanınızla nasıl entegre edileceğini bilmesi zor Verilerin öngörülemeyen büyümesi Olası güvenlik sorunları, örneğin tüm disk alanını kaplayarak bir sistemi çökertebilirsiniz

Burada iyi bir makale var: http://searchsqlserver.techtarget.com/tip/1,289483,sid87_gci1098157,00.html


4
+1 Entegrasyon ve güvenlik sonuçları için. Bunlar, diğer yanıtların çoğu performans hakkında konuştuğunda dikkate alınması gereken orijinal bir açıdır. Entegrasyon sonuçlarıyla ilgili olarak, makul varsayılan kontrol boyutları sağlamak için meta veriler kullanan tüm araçların (rapor yazarları veya form tasarımcıları gibi) tüm sütunlar için çok daha fazla çalışma yapılması gerekir varchar(max).
Hayal Kırıklığı

Veritabanı ile entegrasyon bildiğim en saçma şey. Sadece bir kez yapılan ithalat ise daha önce LEN fonksiyonu ile veri kontrol edebilirsiniz.
Maxim

30

Kabul edilen cevapta verilen bağlantıya göre:

  1. Bir nvarchar(MAX)alanda saklanan 100 karakter, bir nvarchar(100)alandaki 100 karakterden farklı olarak saklanmaz - veriler satır içi olarak saklanır ve 'satır dışında' veri okuma ve yazma yükünüz olmaz. Yani endişelenmenize gerek yok.

  2. Boyut 4000'den büyükse, veriler otomatik olarak 'sıra dışı' olarak saklanır, bu da istersiniz. Yani endişelenme de yok.

Ancak...

  1. Bir nvarchar(MAX)sütunda dizin oluşturamazsınız . Tam metin dizine ekleme özelliğini kullanabilirsiniz, ancak sorgu performansını artırmak için sütunda dizin oluşturamazsınız. Benim için bu anlaşmayı kapatıyor ... her zaman nvarchar (MAX) kullanmak kesinlikle bir dezavantaj.

Sonuç:

Tüm veritabanınız boyunca dizinlenebilen ve alan ve erişim süresini boşa harcamayan bir tür "evrensel dize uzunluğu" istiyorsanız, kullanabilirsiniz nvarchar(4000).


1
fyi Bu soruya cevap olarak gönderilmiş orijinal soruya eklenen bir düzenleme oldu
Tim Abell

1
Teşekkürler, benim için bu son cevap. Kendime aynı soruyu sordum - neden nvarchar(max)her zaman kullanmıyorsunuz - stringC # gibi ? - ama nokta 3) (indeks sorunu) cevap veriyor.
SQL Polisi

1
Bir düzenleme eklendi. Bir çeşit "evrensel dize uzunluğu" olarak, her zaman kullanabilirsiniznvarchar(4000)
SQL Police

@SQLGeorge Martin Smith'in sütunları hiç olmadığı kadar geniş beyan etme performansını sorgulama etkisi üzerindeki bu mükemmel cevaba bakın
billinkc

@billinkc Teşekkürler, bu harika bir makale. Tamam, bu yüzden boyut gerçekten mükemmelliği etkiler. Cevabı tekrar düzenleyeceğim.
SQL Polisi

28

Bazen veri türünün içindeki veriler üzerinde bir anlam ifade etmesini istersiniz.

Diyelim ki gerçekten 20 karakterden uzun olmaması gereken bir sütununuz var. Bu sütunu VARCHAR (MAX) olarak tanımlarsanız, bazı haydut uygulamaları uzun bir dize ekleyebilir ve bunu asla bilemezsiniz veya engellemezsiniz.

Uygulamanız bu dizeyi bir daha kullandığında, dizenin uzunluğunun temsil ettiği etki alanı için mütevazı ve makul olduğu varsayımı altında, öngörülemeyen ve kafa karıştırıcı bir sonuç elde edersiniz.


9
Buna ve diğer bazı yorumlara katılıyorum, ancak yine de bunun iş kademesinin sorumluluğu olduğunu iddia ediyorum. Veritabanı katmanına ulaştığında, ne kadar gülünç uzun olursa olsun, bir selam tutmalı ve değeri saklamalıdır. Burada gerçekten oynamakta olan şey, bir geliştiricinin varchar (255) belirttiği zamanın yaklaşık% 90'ının, niyetinin gerçekten 255 karakter değil, bazı belirtilmemiş orta uzunluk değeri olduğunu düşünüyorum. Ve benim db'deki mantıksız büyük değerler ve öngörülemeyen istisnalar arasındaki ticaret göz önüne alındığında, büyük değerleri alacağım.
Chris B. Behrens

4
Bilinmeyen bir uzunluğu belirtmek için VARCHAR (255) belirtiyorlarsa, tasarladıkları şeyi doğru bir şekilde araştırmamak onların hatasıdır. Çözüm, veritabanının mantıksız değerlere izin vermesi için değil, geliştiricinin işini yapmasıdır.
Tom H

10
yazar için yararlı değil. cevap verdiğiniz bu soruyu açıkça dışladı.
usr

6
@ Chris B Behrens: Katılmıyorum; veritabanı şeması olan iş mantığının bir parçası. Tabloların, ilişkilerin, alanların ve veri türlerinin seçimi tamamen iş mantığıdır - ve bu iş mantığının kurallarını uygulamak için RDBMS'yi kullanmaya değer. Bir nedenle, veritabanına erişen yalnızca bir uygulama katmanının olması çok nadirdir; örneğin, ana iş katmanını atlayan veri içe aktarma ve çıkarma araçlarına sahip olabilirsiniz, bu da kuralları uygulamak için gerçekten DB'ye ihtiyacınız olduğu anlamına gelir.
Vince Bowdren

1
Uzun dizelerin saklanmasını istemiyorsanız veya gerçekten istemiyorsanız, veriler üzerinde mantıklı davranmak daha iyidir. Örneğin, bir PostCode alanı saklıyorsanız, birisinin en fazla 10 olması gerektiğinde yüzlerce veya binlerce karakter girmesine izin verir misiniz. C # ve Entity Framework gibi bir Model First yaklaşımı kullanıyorsanız, modelde boyutunuzu tanımlayabilir ve veritabanına, iş mantığına ve istemci doğrulamasına (jquery doğrulama gibi) uygulamanızı sağlayabilirsiniz. Nvarchar (max) 'ı sadece gerçekten gerekliyse kullanın
Peter Kerr

21

Bazı makaleleri kontrol ettim ve kullanışlı test komut dosyası buldum: http://www.sqlservercentral.com/Forums/Topic1480639-1292-1.aspx NVARCHAR (10) vs NVARCHAR (4000) vs NVARCHAR (MAX) ) ve belirtilen sayıları kullanırken hız farkını bulamıyorum, ancak MAX kullanırken. Kendiniz test edebilirsiniz. Umarım bu yardım.

SET NOCOUNT ON;

--===== Test Variable Assignment 1,000,000 times using NVARCHAR(10)
DECLARE @SomeString NVARCHAR(10),
        @StartTime DATETIME;
--=====         
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='10', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(4000)
DECLARE @SomeString NVARCHAR(4000),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='4000', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO
--===== Test Variable Assignment 1,000,000 times using NVARCHAR(MAX)
DECLARE @SomeString NVARCHAR(MAX),
        @StartTime DATETIME;
 SELECT @startTime = GETDATE();
 SELECT TOP 1000000
        @SomeString = 'ABC'
   FROM master.sys.all_columns ac1,
        master.sys.all_columns ac2;
 SELECT testTime='MAX', Duration = DATEDIFF(ms,@StartTime,GETDATE());
GO

4
İlginç. Kutumda MAX biri 4 kat daha yavaş görünüyor.
stucampbell

4
SQL Server 2012: 10'daki yeni sonuçlar 4k'den iki kat, MAX 4 k'dan 5,5 kat daha yavaş.
cassandrad

1
Zamanın büyük bir kısmı, varchar'dan nvarchar'a (maks.) Örtük kasttır. Bunu deneyin: DECLARE \ @SomeString NVARCHAR (MAX), \ @abc NVARCHAR (max) = N'ABC ', \ @StartTime DATETIME; @StartTime SEÇ = GETDATE (); ÜST SEÇ 1000000 \ @SomeString = \ @abc FROM master.sys.all_columns ac1, master.sys.all_columns ac2; SELECT testTime = 'MAX', Süre = DATEDIFF (ms, \ @ StartTime, GETDATE ()); Gönderiyi almak için değişkenlerden önce \ eklemek zorunda kaldım.
Kvasi

4
SSD üzerinde SQL Server 2014: 150, 156, 716 (10, 4000, MAX).
Maxim,

2
Bu tartışmaya bazı gerçek sayılar eklediğiniz için teşekkür ederiz. Bir test senaryosu oluşturmanın, içgörüyü öğrenmenin en hızlı yolu olduğunu sık sık unutuyoruz.
David C

13

Bunu başka bir güvenlik seviyesi olarak düşünün. Tablonuzu yabancı anahtar ilişkileri olmadan - tamamen geçerli - tasarlayabilir ve ilişkili işlerin tamamen iş katmanında bulunmasını sağlayabilirsiniz. Bununla birlikte, yabancı anahtarlar iyi tasarım uygulamaları olarak kabul edilir, çünkü iş katmanında bir şeylerin karışması durumunda başka bir kısıtlama seviyesi eklerler. Aynı durum alan boyutu sınırlaması için de geçerlidir ve varchar MAX kullanmamak için de geçerlidir.


8

Maks veya metin alanlarını kullanmamanın bir nedeni, çevrimiçi dizin yeniden oluşturma işlemleri gerçekleştirememenizdir; örneğin, SQL Server Enterprise Edition ile bile ONLINE İLE REBUILD = ON.


1
Aynı kısıtlama TEXT alan türü için de geçerlidir, bu nedenle TEXT yerine VARCHAR (MAX) kullanmalısınız.
Will Shaver

bu nedenle kümelenmiş dizinimizi yeniden oluşturamadık. sütunu kendi masasına çıkarabilene kadar çok fazla disk alanına mal oldu (masayı 7 saniyeden daha uzun süre kilitleyemedik)
Choco Smith

4

Tek sorun buldum biz SQL Server 2005 uygulamalarımızı geliştirmek ve bir durumda, biz SQL Server 2000 Sadece öğrendim desteklemek zorunda olmasıydı zor yoldan SQL Server 2000 varchar veya MAX seçenek gibi değil o nvarchar.


2
Öyleyse neden sadece en düşük ortak payda üzerinde gelişmiyor?
binki

4

Alanın 5 ila 10 karakter arasında bir aralıkta olacağını bildiğinizde kötü fikir. Sanırım max'ı sadece uzunluğun ne olacağından emin olmasaydım kullanırdım. Örneğin, bir telefon numarası asla belirli sayıda karakterden fazla olamaz.

Dürüst olmak gerekirse, tablonuzdaki her alan için yaklaşık uzunluk gereksinimleri hakkında belirsiz olduğunuzu söyleyebilir misiniz?

Ne demek istediğini anladım - kesinlikle varchar (max) kullanmayı düşüneceğim bazı alanlar var.

İlginçtir ki MSDN belgeleri oldukça iyi özetliyor:

Sütun veri girişlerinin boyutları önemli ölçüde değiştiğinde varchar kullanın. Sütun veri girişlerinin boyutları önemli ölçüde değiştiğinde ve boyut 8.000 baytı aştığında varchar (max) kullanın.

Burada konu hakkında ilginç bir tartışma var .


2
Telefon numaraları gibi şeyler için, varchar yerine bir char alanı kullanmaktan çok daha hoş olurdum. Depolama alanınızda bir standart koruduğunuz ve farklı ülkelerden telefon numaraları hakkında endişelenmeniz gerekmediği sürece, telefon numarası (biçimlendirme olmadan 10) veya posta kodu (5) gibi bir şey için asla değişken bir alana ihtiyacınız olmamalıdır. veya son dört basamağı eklerseniz 9-10), vb.
TheTXI

Uzunluğu değişebilen telefon numaralarından bahsediyordum. Belki de bunu cevaplamalıyım. Sabit uzunluktaki herhangi bir şey bir char alanı kullanırdım.
RichardOD

Ya da belki de yorumumda nchar veya char demeliyim. :-)
RichardOD

2
Bir telefon numarasındaki karakter sayısı hemen hemen bir iş gereksinimidir. Uluslararası standart kodu numarayla birlikte saklamanız gerekiyorsa, 10'dan fazla olabilir. Ya da, dünyanın bir kısmında bir telefon numarası için 10'dan fazla basamak olabilir. IPV4'ten IPV6'ya geçiş olduğunu düşünün. Hiç kimse eski IPV4 günlerinde 12 basamaktan fazlasına ihtiyaç duyduğumuzu iddia edemezdi. IPV6 yaygınlaşırsa iyi olmayabilir. Bu yine bir süre için bir iş kuralı değişikliğidir.
Söylendiği

2
Bir telefon numarası alanında kaç karakter olabileceğini veya ne tür karakterler olacağını bildiğinize dikkat edin. Sistem bu verileri gerçekten çevirmek için kullanmadığı sürece (bu durumda formatlar hakkında katı olmanız gerekir), kullanıcı oraya meşru bir şekilde beklenmedik şekilde uzun dizeler koyabilir, örn.
Vince Bowdren

4

Veritabanının işi, verileri işletme tarafından kullanılabilmesi için depolamaktır. Bu verileri faydalı kılmanın bir parçası, anlamlı olmasını sağlamaktır. Birisinin ilk adı için sınırsız sayıda karakter girmesine izin vermek anlamlı veriler sağlamaz.

Bu kısıtlamaları iş katmanına eklemek iyi bir fikirdir, ancak bu veritabanının bozulmadan kalmasını sağlamaz. Veri kurallarının ihlal edilmediğini garanti etmenin tek yolu, bunları veritabanında mümkün olan en düşük düzeyde uygulamaktır.


6
IMO, veri uzunluğu sınırlamaları tamamen uygulama büyüdükçe belirli bir süre içinde değişebilen iş kurallarına dayanmaktadır. İş mantığında iş kurallarını değiştirmek db seviyesinden daha kolaydır. Yani, db yeterince esnek olmalı ve izin verilen ilk ad uzunluğu gibi iş kurallarına bağlı olmamalıdır bence, bu çok sizin kullanıcının yaşadığı dünyanın bölümüne bağlıdır.
pencilslate

3

Bir sorun, SQL Server'ın birden çok sürümü ile çalışmak zorundaysanız, MAX her zaman çalışmaz olmasıdır. Bu nedenle, eski DB'ler veya birden çok sürüm içeren başka bir durumla çalışıyorsanız, çok dikkatli olmanız daha iyi olur.


Bence OP bölümünde söylenmeyen varsayım, tamamen 2005+ örneklerle uğraştığı ve uygulamalarının 2000 (veya ack, daha düşük) sürümlerde çalışması gerekmeyeceğidir. Yine de eski sürümleri desteklemeye ihtiyaç duyduğunuzda tamamen katılıyorum!
John Rudy

John Rudy: Böyle bir durum olduğunu hayal edebiliyorum, sadece gideceğimi düşünmediğim zaman bu engellerle karşılaştığımı biliyorum.
TheTXI

Aslında bu, MAX sütun türlerini desteklemeyen SQL CE 4 nedeniyle modern şeyler ile hala yaygın bir sorundur, bu nedenle birlikte çalışabilirlik bir güçlüktür.
JohnC

3

Yukarıda belirtildiği gibi, öncelikle depolama ve performans arasında bir ödünleşmedir. En azından çoğu durumda.

Bununla birlikte, n / varchar (n) yerine n / varchar (Max) seçerken dikkate alınması gereken en az bir faktör daha vardır. Veriler dizine eklenecek mi (örneğin, bir soyadı gibi)? MAX tanımı LOB olarak kabul edildiğinden, MAX olarak tanımlanan hiçbir şey indeksleme için kullanılamaz. ve bir dizin olmadan, verileri bir WHERE yan tümcesinde yüklem olarak içeren herhangi bir arama, veri aramaları için alabileceğiniz en kötü performans olan Tam Tablo taramasına zorlanacaktır.


2

1) SQL sunucusunun nvarchar (max) vs nvarchar (n) ile uğraşırken daha fazla kaynak kullanması gerekir (ayrılan bellek ve işlemci zamanı), burada n alana özel bir sayıdır.

2) Bu performans açısından ne anlama geliyor?

SQL Server 2005'te, 15 nvarchar (max) sütun içeren bir tablodan 13.000 satır veri sorguladım. Sorguları tekrar tekrar zamanladım ve sonra sütunları nvarchar (255) veya daha azına değiştirdim.

Optimizasyondan önceki sorguların ortalaması 2.0858 saniyedir. Değişiklikten sonraki sorgular ortalama 1,90 saniyede geri döndü. Bu temel select * sorgusunda yaklaşık 184 milisaniyelik bir iyileşme idi. Bu% 8.8'lik bir gelişme.

3) Sonuçlarım, performans farkı olduğunu belirten birkaç makaleyle uyumlu. Veritabanınıza ve sorgunuza bağlı olarak, iyileştirme yüzdesi değişebilir. Çok sayıda eşzamanlı kullanıcınız veya çok fazla kaydınız yoksa, performans farkı sizin için sorun olmayacaktır. Ancak, daha fazla kayıt ve eşzamanlı kullanıcı arttıkça performans farkı da artacaktır.


1

Ben dizeleri yastıklı ve varchar (max) çıktı koymak bir udf vardı. Ayarlanan sütun için uygun boyuta geri döndürmek yerine doğrudan kullanıldıysa, performans çok zayıftı. Dize daha küçük bir boyuta yeniden dökmek için udf'un tüm arayanlarına güvenmek yerine udf'u keyfi bir uzunluğa koyarak büyük bir notla bitirdim.


1

eski sistem desteği. Verileri kullanan bir sisteminiz varsa ve belirli bir uzunluk olması bekleniyorsa, veritabanı uzunluğu zorlamak için iyi bir yerdir. Bu ideal değildir, ancak eski sistemler bazen ideal değildir. P =


1

Bir satırdaki tüm veriler (tüm sütunlar için) hiçbir zaman makul olarak 8000 veya daha az karakter almazsa, veri katmanındaki tasarım bunu zorlamalıdır.

Veritabanı motoru her şeyi blob depolama dışında tutmak çok daha verimlidir. Daha küçük bir satırı daha iyi kısıtlayabilirsiniz. Bir sayfada ne kadar çok satır tıklarsanız o kadar iyi olur. Veritabanı daha az sayfaya erişmesi gerektiğinde daha iyi performans gösterir.


1

Testlerim, seçim yaparken farklılıklar olduğunu gösterdi.

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;

0

İlginç bağlantı: TEXT'i kullanırken neden VARCHAR kullanıyorsunuz?

PostgreSQL ve MySQL ile ilgili, bu nedenle performans analizi farklı, ancak "açıklık" mantığı hala geçerli: Neden kendinizi her zaman küçük bir yüzdeyle ilgili bir şey için endişelenmeye zorluyorsunuz? Bir değişkene bir e-posta adresi kaydettiyseniz, '80 karakterle sınırlı' bir dize değil, bir 'dize' kullanırsınız.


1
Bu, bir kişinin yaşının negatif bir sayı olmadığından emin olmak için kontrol kısıtlamalarına sahip olmamanız gerektiğini savunmaya benzer.
Jonathan Allen

Veri doğruluğu ile performans optimizasyonu arasında bir fark görüyorum.
orip

0

Görebildiğim ana dezavantaj, diyelim ki buna sahipsin:

Hangisi size arayüz için gerekli veriler hakkında en fazla bilgiyi verir?

Bu

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

Veya bu?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

3
Bir şirket adının bu bilgi için bir veritabanı tablosuna güvenmek yerine maksimum 50 karakter olabileceğini söyleyen iş mantığını tercih ederim.
Han

Jeff ile aynı fikirdeyim. Kalıcı mağazanın iş kurallarınızı tanımlamak için doğru yer olduğunu düşünmüyorum. Katmanlı bir mimaride kullanıcı arayüzünüz kalıcılık katmanını bile bilmiyordu.
stucampbell

Tabii ki belirli bir boyutla kısıtlanmış bir değer kullanmıyorsanız, örneğin ülke için ISO kodu.
Ben

2
Bunun bir masa def ile ne ilgisi var? Hala iş mantığınız olabilir. Sanırım, bir tablonun nasıl tasarlandığına dair hiçbir anlam ifade etmiyor. İş katmanınızda hala bir tür tanım tasarlamak istiyorsanız, öyle olsun. Daha mantıklı olsa da, yine de iş katmanında depolanmış bir proc kullanmaktır; bir tablo değil def ??
carlos martini

1
Bu popüler değil ama carlos ile hemfikirim, eğer db bir maksimum boyut ayarlarsa, başa çıkmanız gereken şeylerin üzerine inşa ettiğiniz tüm katmanlarda rahat olabilirsiniz. Veritabanınıza birden fazla sistem yazıyorsanız, bu özellikle önemlidir.
Tim Abell

0

Bir dezavantajı, öngörülemeyen bir değişken etrafında tasarlanacak olmanız ve satırlar, sayfalar ve uzantılardan aşamalı olarak oluşan dahili SQL Server veri yapısından yararlanmak yerine muhtemelen yok sayacak olmanızdır.

Bu da C'deki veri yapısı hizalaması hakkında düşünmemi sağlıyor ve hizalamanın farkında olmanın genellikle İyi Bir Şey (TM) olduğu düşünülüyor. Benzer fikir, farklı bağlam.

Sayfalar ve Uzantılar için MSDN sayfası

Satır Taşması Verileri için MSDN sayfası


0

önce bunu düşündüm ama sonra tekrar düşündüm. Performans sonuçları vardır, ancak aynı şekilde alanların gerçekte ne büyüklükte olduğu hakkında bir fikir sahibi olmak için bir dokümantasyon görevi görür. Ve bu veritabanı daha büyük bir ekosistemde oturduğunda zorlar. Kanımca anahtar, izin vericidir, ancak sadece akılda kalmaktır.

tamam, iş ve veri katmanı mantığı konusundaki hislerim burada. DB'niz, iş mantığını paylaşan sistemler arasında paylaşılan bir kaynak ise, elbette bu mantığı uygulamak için doğal bir yer gibi görünüyor, ancak bunu yapmanın EN İYİ yolu değil, EN İYİ yol bir API sağlamaktır, bu izin verir test edilecek etkileşim ve iş mantığını ait olduğu yerde tutar, sistemleri ayrıştırır, bir sistem içindeki katmanlarınızı ayırır. Ancak veritabanınızın sadece bir uygulamaya hizmet vermesi gerekiyorsa, ÇEVİK düşünmeye başlayalım, şimdi ne var? Şimdilik tasarım. Bu tür bir erişim gerekiyorsa ve ne zaman gerekiyorsa, bu verilere bir API sağlayın.

Açıkçası, bu sadece ideal, eğer mevcut bir sistemle çalışıyorsanız, muhtemelen en azından kısa vadede farklı bir şekilde yapmanız gerekecek.


-1

Bu, bir performans sorununa neden olur, ancak veritabanınız küçükse hiçbir zaman gerçek sorunlara neden olmayabilir. Her kayıt sabit sürücüde daha fazla yer kaplar ve aynı anda çok sayıda kayıtta arama yapıyorsanız veritabanının diskin daha fazla bölümünü okuması gerekir. Örneğin, küçük bir kayıt bir sektöre 50 sığabilir ve büyük bir kayıt 5'e sığabilir. Büyük kaydı kullanarak diskten 10 kat daha fazla veri okumanız gerekir.


5
-1. Bir nvarchar(max)sütunda saklanan 100 uzunluklu bir dize, bir sütunda olduğundan daha fazla disk alanı gerektirmez nvarchar(100).
Martin Smith

Sakladığınız verilerin boyutu daha büyükse tanımladığınız doğrudur, ancak bu soru veri türünün performansla ilgili sonuçları veya başka hususları olup olmadığıyla ilgilidir.

-2

Artık kontrollerinizin ne kadar geniş olması gerektiğini tahmin edemeyeceğiniz için ekran tasarımını zorlaştıracaktır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.