# پایگاه‌های داده > SQL Server > مدیریت دیتابیس (Database Administration) >  نوع داده ها و فضای اشغال شده

## صادق صدقی

سلام
وقت بخیر

می خواستم ببینم اگه من یه نوع فیلدم رو که می تونم مثلا Smallint بزارم بیام بزارم Int اما داده ای که وارد میشه توی اون رکورد هاش بین همون رنج smallint باشه مثلا بین یک تا 30.000 توی این رکورد ها ثبت بشه

آیا فضایی که برای اون فیلد توی رکوردش اشغال میشه به مقداری که توی اون فیلد هست ربط داره یه به نوعش؟

این جوری بگم 2 بایت فضا اشغال میشه یا 4 بایت؟ :لبخند گشاده!:

----------


## in_chand_nafar

حافظه تخصیص داده شده Small Int دو بایت است اما اگر مثلا مثالتون قصد ذخیره داده اعشاری داخل این فیلد دارید باید حواستون به قسمت اعشار هم باشد (در این نوع دیتا تایپ قسمت اعشار حذف می شود)

این هم یه لینک خوب

----------


## صادق صدقی

نه منظوره من رو متوجه نشدی 

می دونم انواع داده ها رو

منظوره من اینه اگه مثلا شما یه دیتا تایپی رو بجای nvarchar(50)  بگیری Nvarchar(1000) توی دیتا تا بیس فرقی می کنی فضای اشغال شدش؟

به فرض اینکه در هر 2 نوع مقدار "sssss" وارد بشه
یعنی مقدار هاشون در اصل یکسانن فقط دینا تایپ ها بزرگتر از هم دیگه هستند

ایا فضای اشغال شده شون یکی یه؟

----------


## in_chand_nafar

خوب سوال اول شما در مورد Smallint بوده و اشاره به دیتا تایپ های  کارکتری نشده بود ....
دیتا تایپ کاراکتری به دو دسته تقسیم میشن (Fixed Length,Variable Length)
Fixed Length :
مثل Char و Nchar که در اون صورت طول اون رشته رو داخل پرانتز برایش مشخص می کنیم
Char(5)
یعنی اینکه داده من حداکثر طولش 5 کارکتر و سمت SQL حافظه مربوط به اون* 5 بایت* تخصیص داده میشه حتی اگر شما 3 کاراکتر داخل اون ذخیره کنید 2 کارکتر کابقی به شکل Space ذخیره میشه و طول 5 بایت برایش اشغال میشه
Nchar(5)
 یعنی اینکه داده من حداکثر طولش 5 کارکتر و سمت SQL حافظه مربوط به اون *10 بایت* تخصیص داده میشه حتی اگر شما 3 کاراکتر داخل اون ذخیره کنید 2 کارکتر کابقی به شکل Space ذخیره میشه و طول 10 بایت برایش اشغال میشه ** N مخفف National است و مشخص می کند که دیتا تایپ مورد نظر ما یونی کد است

Varibale Length 
طولشان متغییر است و به ازای ذخیره شدن مقدار طول آن ها (حافظه تخصیص یافته به آن)تنظیم می شود 
برای مثال 
Varchar(5) 
یعنی حداکثر می توانیم 5 کارکتر را داخل آن ذخیره کنیم اگر یک دیتا 3 کارکتری داخل آن ذخیره کنیم حافظه مربوط به آن 3 بایت می شود
NVarchar(5) 
یعنی حداکثر می توانیم 5 کارکتر را داخل آن ذخیره کنیم اگر یک دیتا 3 کارکتری داخل آن ذخیره کنیم حافظه مربوط به آن 6 بایت می شود ** N مخفف National است و مشخص می کند که دیتا تایپ مورد نظر ما یونی کد است

----------


## صادق صدقی

مرسی .عالی و کامل بود
این در موضوع راجبه داده های عددی چطوری یه؟

----------


## in_chand_nafar

نه دوست عزیز در مورد داده های عددی بگم که فضای تخصیص داده شده به نوع دیتا تایپ بستگی  داره 
و فضا به طور کامل تخصیص داده می شود
مثلا int  چهار بایت حافظه می گیرد و...
غیر از نوع داده Decimal  که بستگی به تنظیمات اون داره
--------------------------------------
اما در مورد Performaance دیتا تایپ و... باید چند نکته را درنظر داشته باشی
1- اگر جدولی طراحی می کنید که یکی از فیلدهای آن امکان ورود مقدار ندارد به جای پاس دادن مقدار پیش فرض به ان (در عدد صفر و در رشته Blank) به این فیلد مقدار Null را پاس دهید و اگر می بینید که تعداد Nullهای شما زیاد است بهتر است این نوع فیلدها را Spare Column در نظر بگیرید (در گوگل سیرچ کنید مقاله فارسی گیر می آورید)
2-در برخی از موارد اگر حجم اطلاعات جداول زیاد بوده و میزان اضافه شدن زیاد نیست می توانید جدول را فشرده تا با سرعت بیشتر و IO کمتر دیتا را واکشی نمایید (باز سرچ کنید)

----------


## صادق صدقی

مرسی
آخه من شنیده بودم که بستگی به مقداری داره که توی اون فیلد ذخیره میشه

باشه ممنون
بازم من سرچ می کنم

----------


## حمیدرضاصادقیان

سلام.



> به این فیلد مقدار Null را پاس دهید


البته این مورد اصلا پیشنهاد نمیشه و حتی المقدور پیشنهاد میشه که از مقادیر Null جلوگیری کنید. زیرا مقادیر Null در شرایط مختلف رفتارهای مختلفی از خودش نشون میده که باعث میشه نتیجه درستی از 
Query های مورد نظر بدست نیارید همچنین روی Performance نیز برعکس عمل خواهد کرد.
برای توضیحات تکمیلی پیشنهاد میکنم فصل اول کتاب Inside T-SQL querying 2008 نوشته Itzik-Ben gan رو مطالعه کنید.

----------


## in_chand_nafar

با ذخیره کردن مقدار پیش فرض به ازای یک فیلد عملا حجم را بالا برده و باعث ایجاد IO اضافه می شود. می توانید (Set statistics io را چک کنید)
در ضمن نتایج .... را باید خودتون رعایت کنید خوب اگر قرار بود که در همه فیلد ها مقدار پیش فرض ذخیره بشه اصلا فلسفه وجود Null چی بود
نکته مهم دیگر این است که شما می توانید زمانی که دارید ایندکس می سازید از فیلتر ایندکس استفاده کرده و مقدار Null را در ایندکس شرکت ندهید که حجم ایندکس های شما را پایین بیاورد اما مقدار صفر اگر در Business شما مفهوم داشته باشد و همینطور به عنوان یک مقدار پیش فرض برای فیلدها به کار رود اونوقت فیلتر کردن اون در این نوع ایندکس ها برای شما معنی ندارد
به شخصه از این حالت در یک پروژه ای که جدول اون نزدیک به 1 میلیارد و دویست میلیون رکورد داشت دارم استفاده می کنم و کاملا جواب گرفتم 
مدام IO و زمان اجرای کوئری ها رو دارم چک می کنم حداقل از Design قبلی جدول که کلیه فیلدها با مقدار پیش فزض (0,Blank) ذخیره شده بود خیلی خیلی بهتر است. حالت Sparse Column رو هم به ازای یکی از فیلدهام فعال کردم (البته ناگفته نمونه کمی افزایش حجم با توجه به نوع دیتا تایپ داریم/ فقط به ازای این ستون) و بازهم سرعت اجرای کوئری و .... افزایش یافته است
معتقدم وجود Null الکی نبوده و میشه در شرایطی به خوبی از اون استفاده کرد
این هم چند تا لینک خوب 
https://www.simple-talk.com/sql/perf...tered-indexes/
http://www.dotnettips.info/post/1134...ql-server-2012

https://www.simple-talk.com/sql/t-sq...in-sql-server/

----------


## حمیدرضاصادقیان

پیشنهاد میکنم *این لینک* و *این لینک* که مربوط به MSDN هست رو مطالعه بفرمائید.

اگر Null ها روی سرعت و نتایج تاثیر مثبتی میذارند ، پس فلسفه وجود Default Value ها چی میتونه باشه؟

----------


## in_chand_nafar

بحث ما در مورد کارایی Null است و فلسفه وجود Null کاربرد Default Value یه موضوع دیگر است لینک هایی که من بهش اشاره کردم کارایی Null و ترکیب اون با Sparse Column و در ضمن Filtered Index است. بیشتر کسانی که سراغ Null نمی روند دلیل شون این است که کار کردن با اون سخت است قبول دارم  ....
اما شما وقتی دارید با Default Value به فیلدی مقدار می دهید در واقع به ازای اون فیلد دارید عملا فضایی تخصیص می دهید و این فضا اگر حجم رکوردها بالا برود یعنی IO بیشتر و این یعنی طولانی شدن زمان اجرای کوئری.
پس در برخی از مواقع می شه از Null و ترکیب اون با Sparse Column و در نهایت با Filtered Index بهترین  استفاده رو از اون برد

----------


## حمیدرضاصادقیان

> پس در برخی از مواقع می شه از Null و ترکیب اون با Sparse Column و در نهایت با Filtered Index بهترین استفاده رو از اون برد


بله در بعضی مواقع اجتناب ناپذیر هست ولی نمیشه یک Solution کلی براش ارائه داد اونهم به خاطر سختی پیاده سازی Query ها که اگر یک جا اشتباه بشه ممکنه اتفاقات خیلی فاحشی در نتیجه به ما بده که میتونه ارجحیت داشته باشه نسبت به وجودش.

----------


## in_chand_nafar

به عنوان Solution برای دیتا بیس های کوچک به درد به خور نیست توی مطالبی که اشاره شده توصیه شده (و همینطور توصیه خودم این است) که برای زمانی ازش استفاده بشه که حجم زیاد است و واقعا کارایی مهم است. (در این حالت کسی که به دنبال افزایش Performance است حتما باید به تمامی جوانب کار فکر کند/ مطالبی که شما اشاره کردید و... )
با تشک از آقای صادقی عزیز

----------

