به index گذاری که روی سطح لایه فیزیکی دیتابیس باشه اصطلاحاً پارتیشنبندی گفته میشود.
partition by range
به مثال زیر دقت کنید، در این مثال جدولی با پارتیشن بر مبنای فیلدهای id, age ساختهایم:
SQL> create table sal (id number,age number,name varchar2(20))
partition by range(id,age)
(partition s1 values less than (10,20) tablespace ts1,
partition s2 values less than(20,30) tablespace ts2,
partition s3 VALUES LESS THAN (MAXVALUE) tablespace ts3);
در ادامه گفتهایم که مقدارهای ورودی در پارتیشن s1 باید کمتر از 10,20 باشند و این پارتیشن در tablespace ts1 قرار دارد(یعنی idهای کمتر از ۱۰ و ageهای کمتر از ۲۰)
در ادامه پارتیشن s2 را داریم که مقدارهای کمتر از 20,30 را در خود میگیرد و در tablespace ts2 قرار دارد.
و در ادامه پارتیشن s3 را داریم که اگر رکوردی وارد شد که تو بازهی پارتیشنبندی ما نبود اون رکورد که حالا معلوم نیست بزرگه یا کوچیکه وارد tablespace ts3 شود.
نکته: اسم پارتیشنها زیاد اهمیتی برای ما ندارند.
نکته: اگر عملیات update انجام شود و مقدار عوض شود جابهجایی در پارتیشن نیز رخ خواهد داد.
نکته: تو partition by range بهتره که تمام فیلدها مشخص شوند، یعنی چیز نامعلومی که کاربر بخواد وارد کنه و به مشکل بخوره نباشه
partition by list
من معمولاً از partition by list بیشتر استفاده میکنم، به مثال زیر دقت کنید:
1 create table sal (id number,age number,city varchar2(20))
2 partition by list(city)
3 (partition s1 values (‘tehran’,’abadan’) tablespace ts1,
4 partition s2 values (‘ahvaz,’mashad’) tablespace ts2
5 );
در خط دوم گفتهایم که میخواهیم بر مبنای city پارتیشبندی از نوع لیست انجام بدیم.
خط سوم به این منظور است که اگر دادهای وارد شد با مقادیر tehran, abadan برای فیلد city(به دلیل پارتیشنبندی از نوع لیست رو فیلد city) اطلاعات بر روی tablespace ts1 ذخیرهسازی شود.
خط چهارم به این منظور است که اگر دادهای وارد شده با مقادیر ahvaz,mashad مقادیر بر روی tablespace ts2 ذخیرهسازی شوند.
نکته: وقتی select بر روی sal میگیریم پارتیشنبندی فقط زمانی تاثیر داره که whereما روی فیلد پارتیششده انجام شود تا کش اولیه بر روی SGA به بهترین شکل اعمال شود:
select * from sal where city='tehran';
با زدن کوئری بالا فقط دادههایی رو روی سطح فضای SGA میآره که توی tablespace ts1 هستند یعنی رکوردهایی که شهر اونها یا تهرانه یا آبادان.
مهم: تکرار میکنم خیلی مهمه که کوئریهایی که میزنید بر مبنای پارتیشبندی جدولتان بهینه شده باشد. وگرنه وقتی کوئری بزنید اوراکل به صورت پیشفضر تمام tablespaceهای جدول رو میاره رو فضای SGA و کش میکنه حتی اگه where داشته باشه، مگر اینکه where شما برمبنای پارتیشبندیتان باشد.
س: اگر پارتیشبندی درست انجام نشده باشه و یک رنجی جا افتاده باشد چه اتفاقی میافتد؟
ج: همانطور که در نوشتههای قبل به آن اشاره کردم پارتیشنبندی تنها بر روی دادههای بسیار پر تکرار بهتر است انجام گیرد تا سرعت بهینهتر شود وگرنه در tablespace پیشفرض جدول یعنی tablespace ای که قبل از پارتیشبندی گفتیم که این کاربر جدولهاش روی فلان tablespace باشه دادهها میخوابند.
partition by hash
به این نوع پارتیشنبندی پارتیشنبندی اتوماتیک نیز گفته میشود. این نوع پارتیشنبندی بسیار پرکاربرد است چون فقط تعداد پارتیشنها و نام tablespace را برای اوراکل مشخص میکنیم خود اوراکل به صورت خودکار برمبنای hash دادههای ورودی و شناختش از فایلها بعد از مدتی پارتیشنبندی را به صورت توزیع شده انجام میدهد.
در حقیقت فیلد city رو index میبینه یعنی city همون index پارتیشبندی ما است.
این روش به صورت کلی به این صورت عمل میکند که میاد برای تمام رکوردها id در نظر میگیره (واسه تمام دیتاهای داخل city) و دادهها رو برمبنای id میاد distribute میکنه
create table sal (id number,age number,city varchar2(20))
partition by hash(city)
( partitions 4 store in (tbs1,tbs2,tbs3,tbs4) );
س: میتوان از چند مدل پراتیشنبندی برای یک جدول استفاده کرد؟
ج: خیر، تنها میتوان از یک مدل پارتیشنبندی برای یک جدول استفاده کرد.
س: با بزرگ شدن پروژه ممکن است بخواهیم تعدا پارتیشنها و یا نوع پارتیشنبنید یک جدول را عوض کنیم، آیا امکانش هست؟
ج: این اتفاقی است که بارها شاهد آن بودهام(پارتیشنبندی Dynamic) - به این توجه کنید که شما یک سیستمی به نام data analytics دارید و اگر شما پروژهای را data analytics نکردهاید و جداولتون رو پارتیشنبنید کردهاید به طور خیلی ساده میتوانم بگویم اشتباه کردهاید.
چون آنالیز دیتا چیز خیلی پیچیدهای نیست ولی اگه شما از ساختار دیتاهای خود بیاطلاع هستید و پارتیشنبنید کردهاید و در آینده بخواهید جدولتان را تغییر ساختار و تغییر پارتیشن بدید، دیتابیس شما زیر فشار زیادی خواهد ماند
ولی اگر شرایطی پیشآمد که خواستید اینکار را انجام دهید اول از همه باید دیتابیس را به MOD RESTRICTED ببرید تا کاربران اصلاًنتوانند با دیتابیس تعاملی داشته باشند بعد شروع میکنید به تغییر ساختار جدولتان با ALTER TABLE
یکی از بچههای ا-ل تعریف میکرد که پارتیشنبندی دیتابیس را براساس سالهای ماه انجام دادهاند و تعداد پارتیشنهاشون با ورود دادههای مختلف از بازههای زمانی مختلف به مشکل خورده بود. باید تاکید کنم که حتماً قبل از پارتیشنبندی data analytics را انجام دهید.
توجه داشته باشید حتی اگر میخواهید پارتیشنبندی برمبنای TimeStamp داشته باشید، پارتیشنبندی ماهانه و روزانه بهتر است انجام ندهید. تنها فقط وقتی به این صورتها پارتیشنبندی انجام دهید که سیستم شما آفلاین باشد(یعنی هیچ تراکنشی رو آن انجام نشود و فقط برای گزارشگیری باشد)(Warehouse)
دلیل آن هم این است که چون وقتی شما روز به روز پارتیشنبندی میکنید کل ساختار DataFileهاتون بهم میریزه اینکار شاید دیتابیس رو چندین ساعت وارد mod restricted کنه و یا سرویسها رو قطع کنه پس دیتابیس عملاً کار نمیکنه
نکته: تغییر مدل آنالیز داده آن هم هر روز به طور کل یک عمل اشتباه است. مگر دیتابیس (Warehouse(scope grid باشد نه (Transactional(scope row
س: چی کار میکنند که حجم داده آنقدر بالا میرود؟
ج: تو سیستمهای مخابراتی حجم داده ممکنه در عرض ۱ ساعت ترابایتها برسه(لاگ تمام سوییچها و روترها) به عنوان مثالی دیگر زمانی که سیگنال بخواهید ذخیره کنید، در عرض ۱ ساعت ذخیره سیگنال صدای ۱۵۰ تا خط مخابراتی میشه ۱ ترابایت و در این مورد ما مجبوریم دیتابیس رو هر ۱ ساعت فلاش کنیم چون نمیخوایم دیتا رو به صورت دائمی نگهداری کنیم (به این دلیل در دیتابیس اینکار را میکنیم و دیتابیس را فلاش میکنیم که بافری نداریم که تحمل این حجم داده رو داشته باشه)
س: row scope و grid scope به چه معناست؟
ج: row scope یعنی من خط به خط رکوردها رو میبینم همین چیزهایی که تا به حال گفتم. grid scope یعنی من داده رو یه grid(شبیه توری) میبینم و مدل داده از زوایای مختلف برای ما فرق خواهد داشت.
نکته: پارتیشنبندی رو warehouse با پارتیشنبندی روی transactional database فرق میکند. در warehouse مدل نگاه کردن به دیتا و map دیتا کلاً فرق میکنه نسبت به مدل transactional