Re: Holes in mysql primary key and other db issues...

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



At 2:49 PM -0600 3/4/07, Larry Garfield <larry@xxxxxxxxxxxxxxxx> wrote:
On Sunday 04 March 2007 1:15 pm, Mike Shanley wrote:
 Stut wrote:
 >> I have a sidebar on my site that gets a few random articles from that
 >> table, prints the titles, small blurbs, and a link. The link goes to
 >> the main article. I get the random IDs outside of mysql because I've
 >> made it more likely for newer articles to be chosen than older
 >> ones... This, accomplished via ID, because it's much easier to SELECT
 >> count(*) and slant my randomization to the last 25% of ID numbers
 >> than any other way I can think of...
 >>
 >> Of course, this means that having holes results in empty sidebar
 >> boxes... And that's not too good lookin...
 >
 > How are you selecting random entries? A common way to do this is to
 > use the MySQL rand() function, but that is exceedingly slow.
 >
 > I would suggest that you get a list of (or a subset of) the IDs in the
 > table, use PHP to randomly select however many you need and then get
 > the full data for those. You can't rely on the IDs, and the work
 > involved in resetting all the IDs such that they're sequential without
 > gaps is not worth it.

 I use mt_rand(0,$max_rows) to get each of my values and send the call.
 Getting an array of IDs sounds alright for now, but also sounds like it
 gets increasingly slower and the table is expanded. I'll give it a try
 though.

As Stut said, "holes" in the sequence are not a problem, they're a
feature. :-)  They are guaranteed only to be a unique id.  You have no other
guarantee about them, including the order in which they exist in the
database.  It is perfectly legal in SQL to add 5 records in order to a table,
get an auto_increment added for each, then select the whole table and get
them in a non-numeric order unless you explicitly order them.  The ID is for
reference purposes only, not for ordering or anything else.

What I've done in the past for selecting "three random items from the last 10"
(which sounds close to what you're doing) is something like this:

$result = mysql_query("SELECT * FROM foo ORDER BY timefield DESC LIMIT 10");
$records = array();
while ($record = mysql_fetch_object($result)) {
  $records[] = $record;
}
array_shuffle($records);
for ($i=0; $i < 3; ++$i) {
  $use[] = $records[$i];
}

Now you have an array, $use, that is 3 random entries from the last 10,
ordered by a time field.  The unique ID is irrelevant to that, as it should
be.



This is getting to be more of a MySQL question, but to emphasize again...the autonumbered sequence # is *only* to provide a unique ID. It is normally used as a 'surrogate key' in the database, and is used to link other tables to this one. If you renumber this table, that means you would have to update all tables this refers to.

This set of queries should do the trick, though (untested; need to doublecheck edge cases of max/min id, 0 & 0.999999.... random #'s):

	select max(id) from your_table into @max_id
	select * from your_table where id > ceil(rand() * @max_id) limit 1

For more info, see:

	http://dev.mysql.com/doc/refman/4.1/en/user-variables.html
	http://dev.mysql.com/doc/refman/4.1/en/mathematical-functions.html


	-steve

PS. If you *really* wanted to renumber the database, you should be able to drop and then re-add the auto_increment column, but that's a bad idea (tm) and don't tell anyone I told you how to do it :)


--
+--------------- my people are the people of the dessert, ---------------+
| Steve Edberg                                http://pgfsun.ucdavis.edu/ |
| UC Davis Genome Center                            sbedberg@xxxxxxxxxxx |
| Bioinformatics programming/database/sysadmin             (530)754-9127 |
+---------------- said t e lawrence, picking up his fork ----------------+

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php


[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux