PDA

View Full Version : چندين ميليون ركورد و نحوه ی بایندینگ



Moslemu
دوشنبه 22 مهر 1387, 18:54 عصر
سلام.
راجع به اين موضوع جستجو كردم، اما چيزي پيدا نكردم!

اينكه راهكار اصولي كار با چندين ميليون ركورد چيه؟
در ضمن اينكه سرعت خواندن، افزودن، ويرايش و حذف و ذخيره شدن اين تغييرات در زمان بسيار اهميت دارد!

jaza_sa
دوشنبه 22 مهر 1387, 19:40 عصر
سلام.
راجع به اين موضوع جستجو كردم، اما چيزي پيدا نكردم!

اينكه راهكار اصولي كار با چندين ميليون ركورد چيه؟
در ضمن اينكه سرعت خواندن، افزودن، ويرايش و حذف و ذخيره شدن اين تغييرات در زمان بسيار اهميت دارد!
میشه از یک ترفند یا تکنیک در چنین مواقعی استفاده کرد و اون اینکه
موقع درج ، رکورد مربوطه رو در دیتابیس ذخیره کنیم. درصورتی که درج با موفقیت انجام شد ، اون رکورد رو مثلا از TextBox ها بخونیم و در DataGridView یک ردیف اضافه کنیم و اون اطلاعات خاص رو فقط نمایش بدیم
با این روش دیگه نیاز نیست تا اون همه رکورد رو دوباره از دیتابیس بخونیم و مجددا نمایش بدیم
برای ویرایش و حذف هم به همین ترتیب
یعنی در پس زمینه ، اطلاعات رو به دیتابیس میفرستیم و در ظاهر فقط رکورد مربوطه رو با استفاده از فیلدهایی که کاربر پر کرده ، در DataGridView بروز میکنیم

Moslemu
دوشنبه 22 مهر 1387, 19:56 عصر
خيلي ممنون بابت جوابتون.

اما به نظر اين كار عملي نمياد:
اولاً DataGridView كه Binding شده!
ثانياً اگر Binding نباشه، براي انجام عملياتهاي ديگه وقت زيادي صرف ميشه. مثلاً برا جستجو يا فيلتر يا ... .

مهران رسا
دوشنبه 22 مهر 1387, 23:32 عصر
نمایش رکورد ها
به نظر من استفاده از Datagrid ایده جالبی نیست . برای کنترل بهتر در نمایش رکورد ها ، می تونید از Listview استفاده کنید . اطلاعات رو از بانک بخونید و به صورت دستی و اون طوری که صلاح می دونید در Listview اضافه کنید .

جستجو
برای جستجو سریع و دقیق در چنین حجمی از اطلاعات ، فکر می کنم روش Index گذاری بهترین روش باشه .

Alen
سه شنبه 23 مهر 1387, 10:59 صبح
خيلي ممنون بابت جوابتون.

اما به نظر اين كار عملي نمياد:
اولاً DataGridView كه Binding شده!
ثانياً اگر Binding نباشه، براي انجام عملياتهاي ديگه وقت زيادي صرف ميشه. مثلاً برا جستجو يا فيلتر يا ... .

اين ايده من شايد درست نباشه ولي من از اين روش استفاده مي كنم
سعي ميكنم هيچ وقت چند ميليون ركورد رو همزمان به كاربر نمايش ندم چون حتي اگه از نخ كشي هم استفاده كنم در صورت تعداد بسيار زياد ركوردها بازم اين كار وقت گيره و ممكنه زياد تر از حد انتظار طول بكشه پس سعي ميكنم با گرفتن يك محدوده از كاربر فقط ركوردهاي محدودي رو نمايش بدم
و در مورد جستجو و فيلترينگ من سعي مي كنم از query ها بيشترين استفاده رو بكنم يعني اطلاعات تا جاي ممكن در سرور محدود بشه يعني اگه به چند صد هزار ركورد احتياج دارم همونا رو از سرور بگيرم نه اينكه چن ميليون بگيرم بعد چند صد هزارتاش رو نمايش بدم (كه فكر ميكنم رو استفاده بهينه از حافظه هم تاثير داره)
اين ايده منه اگه غلطه خواهش ميكنم دوستان بفرمايند تا متوجه بشم
اگرم نه كه در اين صورت متدي كه دوست خوبم jaza_sa معرفي كرده گره گشاست

Moslemu
سه شنبه 23 مهر 1387, 12:32 عصر
مسئله اينه كه فقط نمايش و جستجوي ركوردها مورد نظر نيست و همه‌ي عملياتي كه با يه بانك‌اطلاعاتي انجام مي‌شه اينجا نيازه.
از طرفي اين كه كاربر با كدوم ركوردها سر و كار داره اصلاً قابل تشخيص نيست؛ نه از طرف برنامه نويس نه از طرف كاربر. بلكه در هر لحظه، تمامي ركوردها فعال هستند و ممكنه كه از هر كدومشون استفاده بشه!

Alen
سه شنبه 23 مهر 1387, 12:58 عصر
اعمال اصلي بر روي يك DB درج ، ويرايش ، حذف ،جستجو و واكشي است
من فكر نمي كنم تعداد ركوردها بر روي اعمالي مثل درج و حذف و ويرايش تاثيري آنچناني داشته باشد ، خصوصا در پايگاه داده هاي قوي در مورد جستجو ايندكس گذاري مناسب مسلما روش خوبي خواهد بود و در مورد واكشي اگر بخواهيد تعداد زيادي ركورد واكشي شوند چاره اي جز از دست دادن زمان نداريد مگر اينكه به نحوي تعداد ركوردهاي واكشي شده را محدود نماييد
البته اين ايده ها سرچشمه گرفته از اطلاعات من است . خوشحال مي شوم اگر اساتيد من رو متوجه اشتباهاتم كنند

jaza_sa
سه شنبه 23 مهر 1387, 19:21 عصر
میتونید اطلاعات رو بصورت تدریجی نمایش بدید
اگر به نرم افزار Office Word دقت کرده باشید ، وقتی یک فایل با تعداد صفحه زیاد رو میخواد باز کنه ، صفحات رو به ترتیب لود میکنه تا تموم بشن
میشه اینکار رو با استفاده از یک ترد انجام داد !!!

Moslemu
سه شنبه 23 مهر 1387, 19:27 عصر
ممنون.



من فكر نمي كنم تعداد ركوردها بر روي اعمالي مثل درج و حذف و ويرايش تاثيري آنچناني داشته باشد...

اما اگر بخوايم اين تغييرات (حذف، اضافه و ويرايش) در باينديگ اعمال بشه بايد بانكمون رو Fill كنيم؛ نه؟!
خوب برا Fill كردن فرقي نداره كه چه عملي انجام شده باشه.



میتونید اطلاعات رو بصورت تدریجی نمایش بدید
...
از شما هم خيلي ممنونم.
ولي مسئله فقط نمايش دادن همه‌ي ركوردها در اولين با نيست؛ كار با بانك‌اطلاعاتيه!!!

jaza_sa
سه شنبه 23 مهر 1387, 19:38 عصر
ممنون.



اما اگر بخوايم اين تغييرات (حذف، اضافه و ويرايش) در باينديگ اعمال بشه بايد بانكمون رو Fill كنيم؛ نه؟!
خوب برا Fill كردن فرقي نداره كه چه عملي انجام شده باشه.



از شما هم خيلي ممنونم.
ولي مسئله فقط نمايش دادن همه‌ي ركوردها در اولين با نيست؛ كار با بانك‌اطلاعاتيه!!!

مشکلتون دقیقا کجاست ؟
درج ، حذف ، ویرایش : که مشکلی از لحاظ سرعت نداره
انتخاب ، فیلتر : تا اونجایی که من میدونم چاره ای نیست ، کاربر باید صبر کنه. فقط میتونید کاری کنید که بجای اینکه خیلی صبر کنه و همه اطلاعات رو یهو ببینه ؛ اطلاعات رو به مرور ببینه و فقط برای لود کامل اطلاعات صبر کنه که روشش هم استفاده از ترد است.

Moslemu
سه شنبه 23 مهر 1387, 19:46 عصر
استفاده از دستورات SQL معمولاً خيلي كار رو راحت مي‌كنه اما مي‌خوام بدون اينكه توي اين كار دخالتي داشته باشم و با استفاده از dataAdapter، Binding و ابزار VS9 اين اعمال رو انجام بدم.

xxxxxxxxxx
سه شنبه 23 مهر 1387, 22:48 عصر
سلام. با مطالب Alen موافقم ضمن اينكه قبلا درجستجو موارد خوبي يافتم در رابطه با كار با اطلاعات زيادكه چند نكته كه يادم مانده عرض مي كنم اگر اشكالي داشت خوشحال ميشوم عيبش رابگوييد:
1.سعي نكنيد ولزومي هم ندارد همه اطلاعات را در حافظه دستگاه بريزيد بالاخره جايي كم مي آورد وبرنامه قفل ميشود.
2.براي جستجوي سريع راهكارهايي مثل ايندكس خوشه اي ويا تقسيم اطلاعات در چند بانك با توجه به فيلد خاصي (مثل سال ورود اطلاعات يا نيم سال تحصيلي) وكاربر را مجبور كردن به ورود اطلاعات آن فيلد جهت مراجعه به آن بانك .
3-استفاده از پروسجر هاي بانك در رابطه با حذف و ويرايش و ايجاد وجستجو.
4-عدم استفاده از گريد ويو يا حداقل استفاده ركوردهاي خاصي (مثلا 100تاي آخريا ركوردهاي توليدي همان روز) يا استفاده از گريود ويو صفحه اي كه در هر صفحه فقط تعدادي (20) را نمايش دهد(البته اين آخريي يك ايده بود خودم استفادش نكردم ولي مقالاتي را در موردش خواندم).
5-از فكر بايند كردن و فلتر داخل ديتاست يا ديتا تيبل براي همه ركوردها بياد بيرون وسعي كنيد پس از اتمام ورود شروط جستجو با زدن دكمه نمايش بايك ارتباط به بانك فقط ركورد هاي مطلوب را fill كنيدودرمرحله اول همه تيبل خالي بماندضمنا قبل از پر وخالي كردن تيبلتان براي نتايج جستجو بايندها و eventهاي ممكن را قطع و پس از تثبيت وضعيت مجددا وصل نماييد...
بقيه اش را حضور ذهن نداردم ولي خلاصه بجاي استفاده از حافظه از ارتباطهاي بيشتر و عملياتهاي بانك استفاده ببريد.
بيشتر مطالب فوق تكرار گفته هاي دوستان همين سايت بوده.

Alen
سه شنبه 23 مهر 1387, 22:59 عصر
4-عدم استفاده از گريد ويو يا حداقل استفاده ركوردهاي خاصي (مثلا 100تاي آخريا ركوردهاي توليدي همان روز) يا استفاده از گريود ويو صفحه اي كه در هر صفحه فقط تعدادي (20) را نمايش دهد(البته اين آخريي يك ايده بود خودم استفادش نكردم ولي مقالاتي را در موردش خواندم).
5-از فكر بايند كردن و فلتر داخل ديتاست يا ديتا تيبل براي همه ركوردها بياد بيرون وسعي كنيد پس از اتمام ورود شروط جستجو با زدن دكمه نمايش بايك ارتباط به بانك فقط ركورد هاي مطلوب را fill كنيدودرمرحله اول همه تيبل خالي بماندضمنا قبل از پر وخالي كردن تيبلتان براي نتايج جستجو بايندها و eventهاي ممكن را قطع و پس از تثبيت وضعيت مجددا وصل نماييد...


بله در تایید صحبتهای دوستمون بایند کردن زیاد جالب نیست و معایبش بیشتر ازمزایاش هست
و البته شاید مواردی باشد که بایند بهترین راه (اگه میگفتم تنها راه بهتر بود) موجود باشد
به فرض وجود چنین مواردی هم باید سعی کرد تا با راهکارهایی حداکثر کارایی را داشته باشیم (یعنی باز هم همه رکوردها رو به کاربر نشون ندیم)

linux
چهارشنبه 24 مهر 1387, 08:25 صبح
:) اکثرا این مشکل دوستانی هست که قبلا با برنامه های مثل فاکس پرو کارکردند و دوست دارند که همه رکوردها را بریزند جلوی کاربر بدبخت!
چه احتیاجی هست که شما چند میلیون رکورد را لود کنید در حافظه؟!
یک زمانی لازم دارید که عملیاتی بر روی رکورد ها انجام بگیرد که مشکلی نیست ، که با پروسیجرها انجام می دهید در سایر موارد معمولا با یک جستجوی ساده تعداد رکورد ها برگشتی در حد هست که مشکلی برای نمایش آنها بوجود نمی آید

night_walker
چهارشنبه 24 مهر 1387, 11:11 صبح
با سلام
برای مشکل شما بهترین راه اونه که اطلاعات در سمت خود DB فیلتر شده و سپس به سمت کاربر فرستاده شوند، من فکر نمیکنم که در هیچ حالتی یک کاربر به تمام رکوردهای بانک نیاز داشته باشه این عملا غیر ممکنه در ضمن همون طوری که دوستان گفتن بهتره از Multithreading استفاده کنی و کلا Binding رو فراموش کن اطلاعت رو میتونی مثلا به صورت 10000 رکورد به رکورد بخونی و اونها رو به کاربر نشون بدی. این خوندن اطلاعات تدریجی حتما باید در یک Thread مجزا اتفاق بیفته تا کاربر متوجه اون نشه. در ضمن سعی کن تا حد ممکن از View و Stored procedure استفاده کنی.
در مورد استفاده از Index باید بگم که درسته که Index سرعت خوندن از DB رو بالا میبره ولی به همون نسبت سرعت درج رکورد رو پایین میاره پس در استفاده از اونها مراقب باشید. یعنی هر فیلدی رو Index نکنید. در ضمن فکر کنم که خودت بهترین فرد برای تصمیم گیری در مورد روشهایی که باید استفاده بکنی باشی چون هر بانکی با ساختارش میتونه رفتارهای متفاوت داشته باشه و اگه بانکت از نظر طراحی مشکلی داره بهتره که اون مشکل رو اول برطرف کنی. چون بعضی وقتها مشکل کند بودن در طراحی اشتباه بانک است.

Moslemu
پنج شنبه 25 مهر 1387, 09:07 صبح
با تشكر از همه‌ي دوستان؛ بايد عرض كنم:

اول اينكه چرا شما فكر مي‌كنيد كه كار كردن با چند ميليون ركورد برا ديدن، ويرايش، حذف و ... غير ممكنه؟!!
ممكنه.

دوم. همونطوري كه قبلاً هم گفتم مسئله فقط نمايش دادن ركوردها نيست...

سوم. برا جستجو، بهترين كار به نظر بنده Fill كردن همه‌ي ركوردهاست و بعد فيلتر كردن اونها. چونكه اگه براي هر جستجو بخوايم بانك رو خالي كنيم و براي جستجوي بعدي دوباره پر، خيلي از وقت هدر مي‌ره. اينطور نيست؟!

بازم توجه همه‌ي دوستان رو شاكرم.

Alen
پنج شنبه 25 مهر 1387, 10:26 صبح
با تشكر از همه‌ي دوستان؛ بايد عرض كنم:

اول اينكه چرا شما فكر مي‌كنيد كه كار كردن با چند ميليون ركورد برا ديدن، ويرايش، حذف و ... غير ممكنه؟!!
ممكنه.

دوم. همونطوري كه قبلاً هم گفتم مسئله فقط نمايش دادن ركوردها نيست...

سوم. برا جستجو، بهترين كار به نظر بنده Fill كردن همه‌ي ركوردهاست و بعد فيلتر كردن اونها. چونكه اگه براي هر جستجو بخوايم بانك رو خالي كنيم و براي جستجوي بعدي دوباره پر، خيلي از وقت هدر مي‌ره. اينطور نيست؟!

بازم توجه همه‌ي دوستان رو شاكرم.

در جواب سوال اول باید بگم که نه لااقل من اینطور فکر نمی کنم(مطمئن هستم مابقی دوستان هم همینطور هستند) اگه اینطور بود که باید فاتحه برنامه نویسی پایگاه داده رو می خوندیم صحبت فقط اینه که شما حتی اگه یک qurey تو خود query analayzer هم بنویسی که چند میلیون رکورد رو واکشی کنه زمان زیادی طول خواهد کشید حتی اگه تو محیطی مثل enterprise manager بخواهی رکوردهای جدولت رو ببینی باز هم زمانبر خواهد بود ، وای به اینکه یه سطح هم اضافه بشه و بخواهی اونها رو تو یه program به کاربر نشون بدی البته یه راه حل همانطور که دوستان اشاره کردن استفاده از threading هستش برای حل این مشکل ، که من سعی می کنم از این مورد هم تا جایی که لازم نیست استفاده نکنم
این برای مساله نمایش رکوردها اما برای مابقی مسائل مثل حذف و ویرایش و ...
در این موارد مساله مهم جستجو هست که اگر طراحی DB شما خوب باشه (به عنوان مثال به هنگام سازی منتشر شونده نداشته باشید) و اگر از ایندکس ها به خوبی و به جا استفاده کرده باشید مسلما زمانه جستجو به بهترین نحو بهینه خواهد بود و همینطور زمان انجام چنین عملیاتی
فکر میکنم نظرم راجع به مورد دوم رو هم گفتم
اما مورد سوم شما می خواهید یک یا چند رکورد رو بر اساس فیلدی (یا فیلدهایی) که کاربر به عنوان کلید می دهد جستجو نمایید ، سوال من اینه که چرا از مستقیما از query ها استفاده نمی کنید؟ تا فقط همان چند رکورد را واکشی نموده و به کاربر نمایش دهید . به نظر من واگذار نمودن کارهایی که وظیفه سرور است به سرور راه بهتری هست ضمن اینکه جستجو و واکشی یکی از اصلی ترین وظایف پایگاههای داده است اگر غیر از این می بود به طور حتم اینهمه امکانات برای ایجاد پرس و جوهای مختلف در پایگاههای داده مختلف وجود نداشت . پس بهتر است تقسیم بندی وظایف را تا آنجا که می توانیم به بهترین نحو انجام دهیم و تا حد امکان فقط اطلاعاتی را در هر زمان بازیابی نماییم که به آنها احتباج داریم که هم در زمان و هم در حافظه (و دیگر منابع سیستم )صرفه جویی کنیم .به شخصه شاهد تولید نرم افزارهایی بوده ام که چون اینچنین مواردی را رعایت نکرده اند با افزایش حجم رکوردها به سرعت و پس از چند ماه به مشکل برخورده اند
باز هم تاکید میکنم این مورد آخر صرفا به واکشی اطلاعات ارتباط دارد و برای حذف و ویرایش و . . .
طراحی درست DB اصلی ترین شرط کارآیی می باشد
خوشحال می شوم نظر مابقی دوستان رو هم بدونم تا متوجه اشتباهاتم بشم

jaza_sa
پنج شنبه 25 مهر 1387, 16:00 عصر
منم با نظر شما موافقم
ولی استفاده از Thread رو ترجیح میدم ، بخوصوص که در اینجا که حجم اطلاعات زیاده و ممکنه در یک جستجو چندین هزار رکورد Fetch شه
برای اینکه کاربر منتظر لود و نمایش همه اطلاعات بصورت یکجا نباشه بهتره از این امکان استفاده کرد
همونطور که در نرم افزار های حرفه ای هم میبینید ، از این ویژگی استفاده کردند

Moslemu
جمعه 26 مهر 1387, 10:34 صبح
بازم از همه‌ي دوستان ممنونم.

فكر مي‌كنم كه تقريباً نظر تمامي دوستان استفاده از queryهاي خود موتور پايگاه داده است. و به عبارتي بايندينگ توي اينطور موارد بوقه و كاربرد مؤثري نمي‌تونه داشته باشه.
بايد بگم كه بنده هم تا حالا از همين مورد استفاده مي‌كردم چون نظر خود من هم همين بود.

اما به نظر مي‌رسه كه Visual Studio با اين همه عظمتش راجع به يه همچين مواردي هم امكاناتي رو تعبيه كرده و در اختيار برنامه نويسا قرار داده باشه؛ كه قصد من هم به دست آوردن اطلاعاتي راجع به اون امكانات بود...

مي‌دونم كه تشكر من جبران زحمات دوستان رو جبران نمي‌كنه اما به رسم ادب بازم صميمانه از همه تشكر مي‌كنم.