eshpilen
دوشنبه 15 خرداد 1391, 12:16 عصر
البته من فکر میکنم این رفتاری که دیدم فقط محدود به Timestamp نمیشه و ممکنه کلا بر اساس ستونهایی که مقدار رکوردهای اونا یکی باشه پیش بیاد. ولی چیزی که دیدم و تست کردم بر اساس Timestamp بود.
حالا قضیش چیه.
قضیه اینه که من یکسری رکورد در جدول درج کردم که بیشترشون مقدار Timestamp یکسانی داشتن. بعد کوئری ای داشتم که بر اساس Timestamp مرتب میکرد و البته limit و offset هم برای صفحه بندی داشت. بعد چیزی که دیدم این بود که جای بعضی نتایج در صفحات عوض میشد. یعنی مثلا الان رکورد X در صفحهء 1 آمده، بعدش میدیدی رکورد X در صفحهء 2 هم اومده. بعد کل رکوردهایی رو که در تمام صفحات اومده بودن چک میکردی با دیتابیس میدیدی یک رکورد اصلا در هیچ صفحه ای لیست نشده، که بنظرم طبیعتا بخاطر این بوده که اون رکورد تکراری جاش رو گرفته بوده.
من سعی کردم علت این قضیه رو کشف کنم و یکسری تست انجام دادم، و دست آخر به این نتیجه رسیدم که این قضیه از این ناشی میشه که مقدار بیشتر رکوردها در اون ستونی که بر اساس اون مرتب میکنیم برابر بوده، و اینکه الگوریتم Sort یه جورایی در مکان دقیق رکوردها در هر بار بصورت Non-deterministic عمل میکنه.
خب بعضی الگوریتم ها هستن که اینطورین. و مثلا در بعضی رفرنس ها نوشته که فلان خصیصهء این الگوریتم Non-deterministic هست یا تعریف نشده/تضمین نشده هست.
ممکنه الگوریتم Sort مای اس کیو ال هم در این حالت خاص یک چنین ویژگی ای داشته باشه که مثلا رکوردهایی که از نظر معیار Sort هیچ تفاوتی با هم ندارن ممکنه در کوئری های مختلف در مکانهای مختلفی نسبت به هم بیان. مثلا فرض کنیم رکورد A دارای مقدار 102 در ستون مرتب سازی هست و رکورد B هم دارای مقدار 102 در ستونی که بر اساسش مرتب سازی صورت میگیره. حقیقت اینه که MySQL به شما تضمینی نمیده که همیشه در هر کوئری ای که اجرا میشه ترتیب آمدن A و B یکسان باقی بمونه. یعنی ممکنه در یک کوئری ابتدا A بیاد و بعد B و در کوئری دیگری ابتدا B بیاد و بعد A. از نظر مفهوم کلی مرتب سازی که میشه گفت این قضیه مشکلی نداره، چون در هر دو حالت مرتب سازی بدون اشکاله و این دوحالت از نظر معیار مرتب سازی داده شده، هر دو صحیح هستن. ولی اینکه این ترتیب همیشه ثابت بمونه (به فرض اینکه خود دیتابیس در این مدت دستکاری ای نشده باشه که بتونه مکان فیزیکی رکوردها رو تغییر داده باشه)، بستگی به الگوریتم های استفاده شده و بقیهء اجزای درگیر داره.
حالا این دیتابیس من قبل از اجرای این قضیه دستکاری شده بود و مثلا رکوردهایی رو حذف کرده بودم که باعث میشه یکسری رکوردهای جدیدی که درج میکنید بجای اینکه از نظر فیزیکی در انتهای فایل جدول درج بشن در جای رکوردهای حذف شده ذخیره بشن و این حرفها، اما موقع اجرای این تست ها دیتابیس تغییری نکرده بود که بگیم این ترتیب ممکنه بهم خورده باشه.
بعد من بخاطر همین مشکل، بجای مرتب سازی بر اساس Timestamp از مرتب سازی بر اساس کلید Auto Increment جدول استفاده کردم و مشکل برطرف شد.
کلید Auto Increment اولا از نظر مرتب سازی میتونه بدون مشکل بجای Timestamp استفاده بشه و تازه دقیقتر هم هست، یعنی مثلا اگر دو رکورد در زمان بسیار نزدیکی درج بشن Timestamp اونا (که معمولا دقتش درحد ثانیه هست) میتونه یکسان بشه، اما مقدار Auto Increment کاملا نشون میده که کدام رکورد قبل از دیگری درج شده، و دوما چون مقدار رکوردها در ستون Auto Increment هیچوقت نمیتونه یکسان باشه بنابراین با مشکل و ابهام در زمینهء Non-deterministic بودن مکان دقیق رکوردها نسبت به هم در تمام کوئری ها برخورد نمیکنیم.
گفتم این قضیه رو مطرح کنم ببینم کسی شاید تجربه یا اطلاعاتی در این مورد داشته باشه.
حالا قضیش چیه.
قضیه اینه که من یکسری رکورد در جدول درج کردم که بیشترشون مقدار Timestamp یکسانی داشتن. بعد کوئری ای داشتم که بر اساس Timestamp مرتب میکرد و البته limit و offset هم برای صفحه بندی داشت. بعد چیزی که دیدم این بود که جای بعضی نتایج در صفحات عوض میشد. یعنی مثلا الان رکورد X در صفحهء 1 آمده، بعدش میدیدی رکورد X در صفحهء 2 هم اومده. بعد کل رکوردهایی رو که در تمام صفحات اومده بودن چک میکردی با دیتابیس میدیدی یک رکورد اصلا در هیچ صفحه ای لیست نشده، که بنظرم طبیعتا بخاطر این بوده که اون رکورد تکراری جاش رو گرفته بوده.
من سعی کردم علت این قضیه رو کشف کنم و یکسری تست انجام دادم، و دست آخر به این نتیجه رسیدم که این قضیه از این ناشی میشه که مقدار بیشتر رکوردها در اون ستونی که بر اساس اون مرتب میکنیم برابر بوده، و اینکه الگوریتم Sort یه جورایی در مکان دقیق رکوردها در هر بار بصورت Non-deterministic عمل میکنه.
خب بعضی الگوریتم ها هستن که اینطورین. و مثلا در بعضی رفرنس ها نوشته که فلان خصیصهء این الگوریتم Non-deterministic هست یا تعریف نشده/تضمین نشده هست.
ممکنه الگوریتم Sort مای اس کیو ال هم در این حالت خاص یک چنین ویژگی ای داشته باشه که مثلا رکوردهایی که از نظر معیار Sort هیچ تفاوتی با هم ندارن ممکنه در کوئری های مختلف در مکانهای مختلفی نسبت به هم بیان. مثلا فرض کنیم رکورد A دارای مقدار 102 در ستون مرتب سازی هست و رکورد B هم دارای مقدار 102 در ستونی که بر اساسش مرتب سازی صورت میگیره. حقیقت اینه که MySQL به شما تضمینی نمیده که همیشه در هر کوئری ای که اجرا میشه ترتیب آمدن A و B یکسان باقی بمونه. یعنی ممکنه در یک کوئری ابتدا A بیاد و بعد B و در کوئری دیگری ابتدا B بیاد و بعد A. از نظر مفهوم کلی مرتب سازی که میشه گفت این قضیه مشکلی نداره، چون در هر دو حالت مرتب سازی بدون اشکاله و این دوحالت از نظر معیار مرتب سازی داده شده، هر دو صحیح هستن. ولی اینکه این ترتیب همیشه ثابت بمونه (به فرض اینکه خود دیتابیس در این مدت دستکاری ای نشده باشه که بتونه مکان فیزیکی رکوردها رو تغییر داده باشه)، بستگی به الگوریتم های استفاده شده و بقیهء اجزای درگیر داره.
حالا این دیتابیس من قبل از اجرای این قضیه دستکاری شده بود و مثلا رکوردهایی رو حذف کرده بودم که باعث میشه یکسری رکوردهای جدیدی که درج میکنید بجای اینکه از نظر فیزیکی در انتهای فایل جدول درج بشن در جای رکوردهای حذف شده ذخیره بشن و این حرفها، اما موقع اجرای این تست ها دیتابیس تغییری نکرده بود که بگیم این ترتیب ممکنه بهم خورده باشه.
بعد من بخاطر همین مشکل، بجای مرتب سازی بر اساس Timestamp از مرتب سازی بر اساس کلید Auto Increment جدول استفاده کردم و مشکل برطرف شد.
کلید Auto Increment اولا از نظر مرتب سازی میتونه بدون مشکل بجای Timestamp استفاده بشه و تازه دقیقتر هم هست، یعنی مثلا اگر دو رکورد در زمان بسیار نزدیکی درج بشن Timestamp اونا (که معمولا دقتش درحد ثانیه هست) میتونه یکسان بشه، اما مقدار Auto Increment کاملا نشون میده که کدام رکورد قبل از دیگری درج شده، و دوما چون مقدار رکوردها در ستون Auto Increment هیچوقت نمیتونه یکسان باشه بنابراین با مشکل و ابهام در زمینهء Non-deterministic بودن مکان دقیق رکوردها نسبت به هم در تمام کوئری ها برخورد نمیکنیم.
گفتم این قضیه رو مطرح کنم ببینم کسی شاید تجربه یا اطلاعاتی در این مورد داشته باشه.