简体   繁体   English

使用存储过程在MySQL中随机播放表

[英]Shuffle a table in MySQL with a Stored Procedure

I want to create a procedure in MySQL that can shuffle all my records inside a table. 我想在MySQL中创建一个过程,该过程可以将表中的所有记录洗牌。 So far this is what i have now. 到目前为止,这就是我现在所拥有的。

/*
    SHUFFLE A TABLE PROCEDURE
*/

DELIMITER $$

USE `nologinsdb`$$

DROP PROCEDURE IF EXISTS `shuffle_record_table`$$

CREATE DEFINER=`root`@`localhost` PROCEDURE `shuffle_record_table`()
BEGIN
    DROP TABLE IF EXISTS record_table2;

    CREATE TABLE record_table2 LIKE record_table;

    INSERT INTO record_table2 SELECT * FROM record_table ORDER BY RAND();

    DROP TABLE record_table;

    RENAME TABLE record_table2 TO record_table;
END$$

DELIMITER ;


CALL shuffle_record_table();

and i don't understand something 而且我不明白

SELECT * FROM record_table ORDER BY RAND()

gives me random order, but when i inserting in the record_table2 table it has the same order as the record_table table. 给我随机的顺序,但是当我在record_table2表中插入时,它的顺序与record_table表相同。

i don't understand. 我不明白。

Thanks. 谢谢。

There is no point to shuffle rows in a table. 没有意义洗牌表中的行。 You can shuffle them while retrieving the data using order by. 您可以在使用order by检索数据时将它们混洗。

The physical order of the rows is of no interest to the user. 用户对行的物理顺序不感兴趣。 The storage engine is placing the in the order of the index to optimize the access. 存储引擎按索引顺序放置,以优化访问。

If you use InnoDB tables, they are always stored in primary key order. 如果您使用InnoDB表,则它们始终以主键顺序存储。 So if you SELECT from the table without specifying any other ORDER BY , then you'll the rows in that order. 因此,如果您在不指定任何其他ORDER BY情况下从表中进行SELECT ,则将按该顺序排列行。


Error Code: 1075 Incorrect table definition; <BR> 1075错误的表格定义; there can be only one auto column and it must be defined as a key ==> seems lie i cannot drop primary key, why? 只能有一个自动列,必须将其定义为键==>似乎在撒谎,我无法删除主键,为什么? – Damian –达米安

InnoDB requires that if you have an AUTO_INCREMENT column, it must be the first column in an index. InnoDB要求,如果您有AUTO_INCREMENT列,则它必须是索引中的第一列。 Typically people define it as the primary key index, but if you drop the primary key, you must at least define a different index for it. 通常,人们将其定义为主键索引,但是如果删除主键,则必须至少为其定义一个不同的索引。

Example: create a test table that has an auto-increment primary key. 示例:创建一个具有自动递增主键的测试表。

mysql> create table record_table (id int auto_increment primary key);

mysql> insert into record_table values (1), (2), (3);

It's not allowed to have an auto-increment column that is not part of any key. 不允许具有不属于任何键的自动增量列。

mysql> alter table record_table drop primary key;
ERROR 1075 (42000): Incorrect table definition; 
there can be only one auto column and it must be defined as a key

If we drop the primary key but add a secondary key on the same column, this satisfies InnoDB. 如果我们删除主键但在同一列上添加辅助键,则这满足InnoDB。

mysql> alter table record_table drop primary key, add key (id);
Query OK, 3 rows affected (0.13 sec)

But if we try to make that column have no key, it's also an error. 但是,如果我们尝试使该列没有键,那也是一个错误。

mysql> alter table record_table drop key id;
ERROR 1075 (42000): Incorrect table definition; 
there can be only one auto column and it must be defined as a key

One workaround is to create an extra column in the table and assign random values to it, then you can ORDER BY that column. 一种解决方法是在表中创建一个额外的列并为其分配随机值,然后您可以对该列进行ORDER BY。

mysql> alter table record_table add column sort float;

mysql> update record_table set sort = rand();

mysql> select * from record_table ;
+----+----------+
| id | sort     |
+----+----------+
|  1 | 0.439593 |
|  2 | 0.416936 |
|  3 |   0.7659 |
+----+----------+

mysql> select * from record_table order by sort;
+----+----------+
| id | sort     |
+----+----------+
|  2 | 0.416936 |
|  1 | 0.439593 |
|  3 |   0.7659 |
+----+----------+

You can "reshuffle" the table without having to copy data back and forth, just UPDATE the random values. 您可以“重组”表,而不必来回复制数据,只需更新随机值即可。

mysql> update record_table set sort = rand();

mysql> select * from record_table order by sort;
+----+----------+
| id | sort     |
+----+----------+
|  1 | 0.137319 |
|  3 | 0.329505 |
|  2 | 0.348292 |
+----+----------+

Here http://dev.mysql.com/doc/refman/5.1/en/create-table.html 在这里http://dev.mysql.com/doc/refman/5.1/en/create-table.html
they say that: 他们说:

Use LIKE to create an empty table based on the definition of another table, including any column attributes and indexes defined in the original table : 使用LIKE根据另一个表的定义(包括原始表中定义的任何列属性和索引)创建一个空

It means, that a primary key is also copied to a new table, and preservers the rows order. 这意味着,主键也将被复制到新表中,并保留行顺序。
Just drop the primary key in the new table : 只需将主键放在新表中:

CREATE TABLE record_table2 LIKE record_table;
ALTER TABLE record_table2 DROP PRIMARY KEY;
INSERT INTO record_table2 SELECT * FROM record_table ORDER BY RAND();

----- EDIT ----- -----编辑-----

If the above solution doesn't work since there is an auto_icrement on the primary key column, 如果上述解决方案由于主键列上存在auto_icrement而不起作用,
then try CREATE TABLE x AS SELECT * FROM y , this doesn't copy indexes and keys: 然后尝试CREATE TABLE x AS SELECT * FROM y ,这不会复制索引和键:

create table x( 
  x int primary key auto_increment,
  y int );

insert into x( y ) values( 1 ), (3 ), (2),(5),(4);

select * from x;
+ ------ + ------ +
| x      | y      |
+ ------ + ------ +
| 1      | 1      |
| 2      | 3      |
| 3      | 2      |
| 4      | 5      |
| 5      | 4      |
+ ------ + ------ +

5 rows

create table y as select * from x order by rand();

select * from y;

+ ------ + ------ +
| x      | y      |
+ ------ + ------ +
| 2      | 3      |
| 4      | 5      |
| 3      | 2      |
| 1      | 1      |
| 5      | 4      |
+ ------ + ------ +

5 rows

Look i had same question here and the solution has: 看我在这里有同样的问题,解决方案有:

CREATE TABLE origintable SELECT * FROM origintable2;
ALTER TABLE origintable2 DROP idfield;
CREATE TABLE origintable3 LIKE origintable2;
INSERT INTO origintable3 SELECT * FROM origintable2 ORDER BY RAND();
DROP TABLE origintable2;
ALTER TABLE origintable3 ADD COLUMN idfield INT NOT NULL AUTO_INCREMENT FIRST
, ADD PRIMARY KEY (idfield);
RENAME TABLE origintable TO origintable_bkp;
RENAME TABLE origintable3 TO origintable;
DROP TABLE origintable3;

Works like a charm! 奇迹般有效! new table, suffle data, same sctructure! 新表,数据存储,结构相同!

Hope helps somebody 希望可以帮助某人

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM