簡體   English   中英

使用存儲過程在MySQL中隨機播放表

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

我想在MySQL中創建一個過程,該過程可以將表中的所有記錄洗牌。 到目前為止,這就是我現在所擁有的。

/*
    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();

而且我不明白

SELECT * FROM record_table ORDER BY RAND()

給我隨機的順序,但是當我在record_table2表中插入時,它的順序與record_table表相同。

我不明白。

謝謝。

沒有意義洗牌表中的行。 您可以在使用order by檢索數據時將它們混洗。

用戶對行的物理順序不感興趣。 存儲引擎按索引順序放置,以優化訪問。

如果您使用InnoDB表,則它們始終以主鍵順序存儲。 因此,如果您在不指定任何其他ORDER BY情況下從表中進行SELECT ,則將按該順序排列行。


<BR> 1075錯誤的表格定義; 只能有一個自動列,必須將其定義為鍵==>似乎在撒謊,我無法刪除主鍵,為什么? –達米安

InnoDB要求,如果您有AUTO_INCREMENT列,則它必須是索引中的第一列。 通常,人們將其定義為主鍵索引,但是如果刪除主鍵,則必須至少為其定義一個不同的索引。

示例:創建一個具有自動遞增主鍵的測試表。

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

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

不允許具有不屬於任何鍵的自動增量列。

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

如果我們刪除主鍵但在同一列上添加輔助鍵,則這滿足InnoDB。

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

但是,如果我們嘗試使該列沒有鍵,那也是一個錯誤。

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

一種解決方法是在表中創建一個額外的列並為其分配隨機值,然后您可以對該列進行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 |
+----+----------+

您可以“重組”表,而不必來回復制數據,只需更新隨機值即可。

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 |
+----+----------+

在這里http://dev.mysql.com/doc/refman/5.1/en/create-table.html
他們說:

使用LIKE根據另一個表的定義(包括原始表中定義的任何列屬性和索引)創建一個空

這意味着,主鍵也將被復制到新表中,並保留行順序。
只需將主鍵放在新表中:

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();

-----編輯-----

如果上述解決方案由於主鍵列上存在auto_icrement而不起作用,
然后嘗試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

看我在這里有同樣的問題,解決方案有:

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;

奇跡般有效! 新表,數據存儲,結構相同!

希望可以幫助某人

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM