შემთხვევითი ჩანაწერის ამორჩევა მონაცემთა ბაზის ცხრილიდან

ალბათ ბევრგან დაგჭირვებიათ შემთხვევითი ჩანაწერის ამოღება (random წერილის გამოყვანა ბლოგზე, random ფრაზა, random წიგნი – ბიბლიოთეკის საიტზე, random პროდუქტი – მაღაზიის საიტზე, ა.შ.) და შეიძლება რაიმე კარგი მეთოდიც გაქვთ შერჩეული ამისთვის.
მე კვლევები არ მიწარმოებია :))) ამ საკითხზე. უბრალოდ შემხვდა სასარგებლო სტატია, სადაც ამ მეთოდების განხილვაა მოყვანილი და მათი სისწრაფეებია შედარებული.

მეთოდი 1:

ვიყენებთ RAND() ფუნქციას, რომელიც float ტიპის რიცხვს აბრუნებს 0-დან 1-მდე.
sql მოთხოვნას შემდეგი სახე აქვს: SELECT * FROM `table` ORDER BY RAND() LIMIT 0,1;

როგორც სტატიის ავტორი წერს, მეთოდის პრობლემა მისი შესრულების დროა. MySQL-ს ყველა ჩანაწერი დროებით ცხრილში გადააქვს, თითოეულს ანიჭებს რაღაც შემთხვევით ინდექსს სორტირებისთვის. შემდეგ შედეგებს ასორტირებს და აბრუნებს პირველ ჩანაწერს.

უკეთესი მიდგომის აზრი ის არის, რომ ჯერ შეირჩეს შემთხვევითი რიცხვი და ამ შემთხვევითი რიცხვის მიხედვით ამოირჩეს მხოლოდ ერთი ჩანაწერი.

მეთოდი 2:

იმ შემთხვევაში, თუ თითოეულ ჩანაწერს უნიკალური გასაღები (მაგალითად id) გააჩნია, მაშინ შეგვიძლია ავირჩიოთ შემთხვევითი id უმცირეს და უდიდეს id-ებს შორის და შემდეგ დავაბრუნებინოთ იმ არჩეული id-ის ჩანაწერი.

უდიდესი და უმცირესი id-ის გასაგებად MAX() და MIN() ფუნქციები გამოვიყენოთ.

$range_result = mysql_query( " SELECT MAX(`id`) AS max_id , MIN(`id`) AS min_id FROM `table` ");
$range_row = mysql_fetch_object( $range_result );
$random = mt_rand( $range_row->min_id , $range_row->max_id );
$result = mysql_query( " SELECT * FROM `table` WHERE `id` >= $random LIMIT 0,1 ");
მეთოდი საკმაოდ შეზღუდულია, რადგან შეიძლება ცხრილს უნიკალური გასაღები საერთოდ არ ჰქონდეს. ამიტომ მესამე მეთოდში MySQL-ის LIMIT-ს ვეყრდნობით.

მეთოდი 3:

LIMIT ორ არგუმენტს იღებს. მაგალითად LIMIT 5,10  დააბრუნებს ჩანაწერებს 6-დან 15-მდე. ათვლა 0-დან იწყება.  პირველი არგუმენტი offset-ია (არ ვიცი როგორ ითარგმნება), ხოლო მეორე – offset-დან ათვლილი წამოსაღები ჩანაწერების მაქსიმალური რაოდენობა.

რომ გამოვთვალოთ offset პირველ ჩანაწერამდე – დავაგენერიროთ შემთხვევითი რიცხვი MySQL-ის RAND() ფუნქციის საშუალებით. შემდეგ მიღებული რიცხვი გადავამრავლოთ ცხრილში არსებულ ჩანაწერთა რაოდენობას (ამ რაოდენობას COUNT() ფუნქციის მივიღებთ). რადგან LIMIT მხოლოდ მთელ რიცხვებს იღებს არგუმენტებად, ეს ნამრავლი უნდა დავამრგვალოთ – გამოვიყენოთ FLOOR() ფუნქცია.

FLOOR() არითმეტიკული ფუნქციაა, რომელიც გამოთვლის უდიდეს მთელ რიცხვს გადაცემულ პარამეტრამდე. საბოლოოდ, კოდს ასეთი სახე ექნება:

$offset_result = mysql_query( " SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM `table` ");

$offset_row = mysql_fetch_object( $offset_result );
$offset = $offset_row->offset;

$result = mysql_query( " SELECT * FROM `table` LIMIT $offset, 1 " );
MySQL 4.1 და უფრო მაღალ ვერსიებში ეს ორი მეთოდი შეგვიძლია ასე გავაერთიანოთ:

მეთოდი 4:

SELECT * FROM `table` WHERE id >= (SELECT CEILING( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;

ამ მეთოდს იგივე ნაკლი აქვს, რაც მეორეს. ის მხოლოდ უნიკალურ გასაღებიან ცხრილებთან მუშაობს.

სტატიის ავტორმა მეთოდების სისწრაფეები შეადარა და სოფტის და ჰარდის სპეციპიკაციებს თუ არ ჩავუღრმავდებით, მიახლოებით ასეთი შედეგი მიიღება:

ყველაზე ნელი პირველი მეთოდია. ვთქვათ, რომ მას დროის 100% დასჭირდა შესრულებისთვის.
მეორე მეთოდს 79%.
მესამეს – 13%.
მეოთხეს – 16%.
გამოდის, რომ ყველაზე სწრაფია მესამე მეთოდი.

ecorner – სტენფორდის ”პოდკასტები”

აკადემიური წლის განმავლობაში ყოველ ოთხშაბათს სტენფორდის უნივერსიტეტში The Entrepreneurial Thought Leaders ლექციათა სერია ტარდება. მათი პოდკასტები კი საიტზეა გამოქვეყნებული..

 

ამ ლექციების წასაკითხად სხვადასხვა ცნობილი ორგანიზაციების წარმომადგენლებს იწვევენ. მაგალითად, 2006 წლის შემდეგ სტუმრებს შორის იყვნენ შემდეგი ფირმების, სასწავლო დაწესებულებების და პროექტების წარმომადგენლები:Google, Mozilla, Yahoo!, Microsoft, Nokia, eBay, NVIDIA, Silicon Valley Bank, Google Analytics, InCube Labs, BitTorrent, Tesla Motors,Autodesk, Aruba Networks, LinkedIn, Facebook, OdeoHarvard Business School, London Business School, PodShow, Glu MobileDNA Direct, Genomic Health, Wikia,Warner Music და სხვა.

 

პოდკასტები შეგიძლიათ ამ ლინკზე აირჩიოთ და პირდაპირ მოუსმინოთ ლექციას (რეგისტრაციისა და სხვა პროცედურების გარეშე)

System.out.println(“Hello World”);

ვიპოვე ახალი ’მყუდრო კუთხე’ და გადმოვსახლდი აქ 🙂
ბლოგი უფრო ავტორისთვის არსებობს ალბათ ვიდრე მკითხველისთვის.

თემაც არ შემირჩევია კონკრეტული. ის – რაც დროის რომელიღაც მომენტში იქნება ჩემთვის საინტერესო… 
ზოგადად ალბათ ისევ პროგრამირებაზე დავა :)))))

პ.ს. არ მიყვარს ხოლმე პირველი პოსტის წერა…

DntFearThReapr-ის ფოტო