Database Design

arashdanger

Member
سلام امروز یه سئوال خفن دارم:
فرض کنیم میخواهیم سیستم مسنجر یاهو رو با دیتابیس mysql پیاده کنیم(همون کاری که یاهو کرده) میخواهیم که هر نفر بتونه به مقدار دلخواه دوست به لیستش اضافه کنه(add to friend list) خب برای مثال یه table داریم به نام users که یه همچین شکلی داره:
کد:
    #  # Table structure for table `users`  #
    CREATE TABLE users (    id int(11) NOT NULL auto_increment,    username varchar(255) NOT NULL default '',    name varchar(255) NOT NULL default '',    city varchar(255) NOT NULL default '',    friends text NOT NULL,    PRIMARY KEY  (id),    FULLTEXT KEY friends (friends)  ) TYPE=MyISAM;   
 #  # Dumping data for table `test`  #    
INSERT INTO test VALUES (1, 'arashdanger', 'arash', 'tabriz', 'ali_khafan,ahmad_delon,arashdanger');  
INSERT INTO test VALUES (2, 'ali_khafan', 'ali', 'tehran', 'arashdanger,ahmad_delon');  INSERT INTO test VALUES (3, 'ahmad_delon', 'ahmad', 'shiraz', 'ali_khafan,nasim_2000');
  INSERT INTO test VALUES (4, 'nasim_2000', 'ghanbar', 'tehran', '');


خب این یک حالت ممکنه که اسم دوستان کاربر رو همشو تو یه خانه بریزیم و وسطشون یه ویرگولی چیزی بزاریم که از هم جدا بشن.یه راه دیگه هم هست که مثلا 100 تا ستون به نامهای friend1,friend2,... در نظر بگیریم و بیشتر از این تعداد اجازه ندیم کاربر کسی رو به لیست دوستاش اضافه کنه.راه سوم هم اینه که هر بار که کاربر یه دوست به لیستش اضافه کرد به table یه ستون اضافه کنیم.
اشکالات:
اشکال راه اول اینه که این پیاده سازی کلی بار روی سرور میزاره و هربار که بخواهیم لیست دوستان رو بخونیم باید یه متن رو تکه تکه کنیم و ... حالا فکر کنید اگر بخواهیم ببینیم که مثلا arashdanger دوست چه کسایی هست چقدر طول میکشه به نتیجه برسیم!!!(این بدترین روش بود)
روش دوم ار لحاظ سرعت خیلی خوبه ولی دوتا اشکال داره اول اینکه کاربر بیشتر از مثلا 100 تا نمیتونه دوست توی لیستش داشته باشه و اشکال دوم اینه که احتمالا خیلی از کاربرها همین 100 تا دوست رو هم ندارن و ما با کلی خانه خالی موجه میشیم که زیاد قشنگ نیست و ممکنه اشکالات ثانویه هم بوجود بیاره.
روش سوم رو هم یکی از دوستانم پیشنهاد کرد که همون اشکال خالی موندن خانه هارو داره و اینکه نمیدونم که آیا تو mysql میشه یک ستون به table اضافه کرد یا نه و اگر امکانش هست اینکار چطور انجام میشه و آیا از کل دیتابیس backup میگره و یه ستون اضافه میکنه و دوباره اطلاعات رو توش میریزه یا طور دیگه ای عمل میکنه؟
خب به نظرتون Yahoo چه طور این مشکل رو حل کرده؟ چون هیچکدوم از راه حلهایی که گفتم به درد نمیخورن!!!
(این ID هایی که تو table نوشتم از خودم در آوردم! همونطور هم که میبینین بعضیا مثل خودم خودشون روهم add میکنن که هیچوقت تو یاهو تنها نباشن!!!)
 

arashdanger

Member
من درباره انواع داده ای Enum و Set اطلاعی ندارم ولی فکر میکنم بدرد یه همچین جایی میخورن!!!
اگر کسی در مورد Enum و Set اطلاعی داره لطفا توضیح بده
 

Salman_MP

Member
آقا شما ميتوني يه جدول ديگه مثلاْ به اسم friends بسازي كه كليد مربوط به هر كاربر و كليد هر دوست رو داشته باشه مثلاْ
کد:
CREATE TABLE Friends (uid FOREIGN KEY REFFERENCES TO USERS, fid uid FOREIGN KEY REFFERENCES TO USERS)
از درست بودن سينتكس مطمپن نيستم چون براي ام اس سيكوءل هست ولي بايد از مفهوم كليد خارجي استفاده كني.
 

arashdanger

Member
خوب البته از چیزی که نوشتی زیاد سر در نیاوردم ولی راهی که معمولا برای حل همچین حالتهایی استفاده میکنن اینه که یه جدول دیگه درنظر میگیرن که دوتا فیلد داره:
user_id , friend_id
هربار که یه کاربر یکی دیگه رو به لیست دوستاش اضافه میکنه(دوستش رو add میکنه) یه ردیف به جدول اضافه میشه
البته این روش روش خوبیه ولی بهینه نیست و فکر کنم راه بهتری وجود داشته باشه و احتمالا یاهو کار دیگه ای کرده چون اگر مثلا بخواهیم بینیم که من دوست چه کسایی هستم تو کل این جدول که ممکنه بیشتر از 500 میلیون ردیف داشته باشه جستجو کنه!!!
این 500 میلیون رو هم الکی نگفتم چون یاهو 100 میلیون کاربر داره و اگر بطور متوسط هر کس 5 تا دوست رو add کنه 500 میلیون ردیف ایجاد میشه!!
حالا اگه یه راه حل بهتر به ذهنتون میرسه بگین :D
 

Salman_MP

Member
چیزی که نوشتی دقیقاً همونیه که من گفتم و بهترین راه حله چرا که در هر حالت دیگه ای افزونگی (redundancy) بیشتري بوجود می آد و دیگه اینکه یاهو میتونه از دیتابیسهای توزیع شده (خودمم چیز زیادی ازش نمیدونم ولی از اسمش یه چیزايي فهمیده میشه) استفاده کنه . تازه 500000000 خیلی هم زیاد نیست !!!
 
آخرین ویرایش:

miladmovie

Active Member
همون طور که Salman_MP گفت باید استفاده کنید
این روش خودش بهینه هست و هیچ مشکلی هم نداره اصلا ایجاد یک رابطه درست برای اینه که دیتابیس بهینه باشه
 

arashdanger

Member
سلمان میتونی اون اصطلاح دیتابیسهای توزیع شده رو انگلیسی شو بنویسی که من یه کم در موردش تحقیق کنم؟
 

arashdanger

Member
Salman_MP گفت:
چیزی که نوشتی دقیقاً همونیه که من گفتم و بهترین راه حله چرا که در هر حالت دیگه ای افزونگی (redundancy) بیشتري بوجود می آد و دیگه اینکه یاهو میتونه از دیتابیسهای توزیع شده (خودمم چیز زیادی ازش نمیدونم ولی از اسمش یه چیزايي فهمیده میشه) استفاده کنه . تازه 500000000 خیلی هم زیاد نیست !!!
اینجا نوشته که یاهو از mysql استفاده میکنه حالا راست و دروغش رو نمیدونم!http://www.mysql.com
والا تا اونجا که من فهمیدم این Distributed Database چیزی نیست غیر از یه سیستم که اجازه میده بخشی از اطلاعات دیتابیس روی یک سرور باشه و بخش دیگش روی یک سرور دیگه یعنی ممکنه یک قسمت از اطلاعات یک کاربر در یاهو روی یک سرور باشه و قسمتی روی یک سرور دیگه . اینکار به یک سایت بزرگ اجازه میده که اطلاعاتش رو روی چندتا سرور ذخیره کنه. حالا نمیدونم که این کار تاثیری در سرعت دیتابیس هم داره یا نه؟
درسته 500 میلیون خیلی هم زیاد نیست ولی یه حساب سرانگشتی بکنی میبینی که یاهو با 100 میلیون کاربری که داره اگر در یک لحظه یک ده هزارم این تعداد کاربر آنلاین باشن چنتا query به این table وارد میشه!!!
 
آخرین ویرایش:

Salman_MP

Member
arashdanger گفت:
درسته 500 میلیون خیلی هم زیاد نیست ولی یه حساب سرانگشتی بکنی میبینی که یاهو با 100 میلیون کاربری که داره اگر در یک لحظه یک ده هزارم این تعداد کاربر آنلاین باشن چنتا query به این table وارد میشه!!!
نميخوام الكي از حرفي كه نسنجيده (!!!) زدم دفاع كنم ولي ميشه 10000 نفر كه اگر به فرض دوستمون به طور متوسط هر كي 5 تا دوست داشته باشه ميشه 50000 كوءري. !؟! بد نيست يه كمي به سروره فشار مي آد ولي خوب هر كه خربزه خواهد جور هندوستان كشد !!! يا شايدم هر كه طاووس ميخوره پاي لرزش هم ميشينه !!!
 

جدیدترین ارسال ها

بالا