2010-12-07 2 views
14

Я хочу сгенерировать уникальное случайное целое число (от 10000 до 99999) только чистым mySQL; есть идеи?mysql уникальное количество поколений

Я не хочу генерировать это число в php путем циклирования (сгенерировать номер -> проверить его в базе данных), потому что я хочу использовать некоторое интеллектуальное решение в запросе mySQL.

+0

уникальным по отношению к? – jball 2010-12-07 22:17:33

+0

уникально к чему, другие записи в таблице? – 2010-12-07 22:17:45

+0

уникально для столбца таблицы – hippout 2010-12-07 22:18:31

ответ

-1

Я беспокоюсь о почему вы хотите сделать это, но вы могли бы просто использовать:

SELECT FLOOR(RAND() * 1000000); 

Смотрите полный MySQL RAND documentation для получения дополнительной информации.

Однако, надеюсь, вы не используете это как уникальный идентификатор (используйте auto_increment attribute на достаточно большом беззнаковом целочисленном поле, если это то, что вам нужно), и мне нужно задаться вопросом, почему вы используете MySQL для это, а не скриптовый язык. Чего вы пытаетесь достичь?

0

Функция RAND() генерирует случайное число, но будет не гарантия уникальности. Правильный способ обработки уникальных идентификаторов в MySQL - объявить их с помощью AUTO_INCREMENT.

Например, поле идентификатора в таблице не должно быть поставлено на вставках, и она всегда будет увеличиваться на 1:

CREATE TABLE animal (
    id INT NOT NULL AUTO_INCREMENT, 
    name CHAR(30) NOT NULL, 
    PRIMARY KEY (id) 
); 
20

Хотя это кажется несколько неуклюжими, это то, что может быть сделано для достижения цели:

SELECT FLOOR(10000 + RAND() * 89999) AS random_number 
FROM table 
WHERE random_number NOT IN (SELECT unique_id FROM table) 
LIMIT 1 

Проще говоря, он генерирует случайные числа N, где N является счетчиком строк таблицы, отфильтровывает те, которые уже присутствуют в таблице, и ограничивает остальные установлен в единицу.

Это может быть несколько медленным на больших столах. Чтобы ускорить работу, вы можете создать представление из этих уникальных идентификаторов и использовать его вместо вложенного оператора select.

EDIT: убрана цитата

5

Создание справочной таблицы из последовательных чисел в рандомизированные значения идентификаторов в диапазоне от 1 до 1M:

create table seed (i int not null auto_increment primary key); 
insert into seed values (NULL),(NULL),(NULL),(NULL),(NULL), 
         (NULL),(NULL),(NULL),(NULL),(NULL); 

insert into seed select NULL from seed s1, seed s2, seed s3, seed s4, seed s5, seed s6; 
delete from seed where i < 100000; 

create table idmap (n int not null auto_increment primary key, id int not null); 
insert into idmap select NULL, i from seed order by rand(); 

drop table seed; 

select * from idmap limit 10; 

+----+--------+ 
| n | id  | 
+----+--------+ 
| 1 | 678744 | 
| 2 | 338234 | 
| 3 | 469412 | 
| 4 | 825481 | 
| 5 | 769641 | 
| 6 | 680909 | 
| 7 | 470672 | 
| 8 | 574313 | 
| 9 | 483113 | 
| 10 | 824655 | 
+----+--------+ 
10 rows in set (0.00 sec) 

(Все это занимает около 30 секунд, чтобы работать на моем ноутбуке Вам нужно будет сделать это только один раз для каждой последовательности.)

Теперь у вас есть сопоставление, просто отслеживайте, сколько было использовано (поле ключа счетчика или auto_increment в другой таблице).

1

Единственная разумная идея на полпути, которую я могу придумать, - создать таблицу с конечным пулом идентификаторов, и поскольку они используются, удалите их из этой таблицы. Эти ключи могут быть уникальными и создать сценарий для создания этой таблицы. Затем вы можете вытащить один из этих ключей, создав случайный выбор из доступных ключей. Я сказал «на полпути» разумно и честно, что это был путь к великодушию, но он случайным образом генерирует ключи, пока вы не создадите уникальный, я полагаю.

0

Я попытался использовать этот answer, но это не сработало для меня, поэтому мне пришлось немного изменить исходный запрос.

SELECT FLOOR(1000 + RAND() * 89999) AS random_number 
FROM Table 
WHERE NOT EXISTS (SELECT ID FROM Table WHERE Table.ID=random_number) LIMIT 1 
1

Мое решение, реализованная в CakePHP 2.4.7, чтобы создать таблицу с полем типа один auto_incremental

CREATE TABLE `unique_counters` (
    `counter` int(11) NOT NULL AUTO_INCREMENT, 
    `field` int(11) NOT NULL, 
    PRIMARY KEY (`counter`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

Затем я создал функцию PHP, чтобы каждый раз вставить новую запись, чтение сгенерированный идентификатор и немедленно удалить его. Mysql сохраняет статус своего счетчика памяти. Все числа, сгенерированные являются уникальными, пока вы не сбросите счетчик MySQL или запустить операцию TRUNCATE TABLE

находку ниже модели, созданной в CakePHP, чтобы реализовать все

App::uses('AppModel', 'Model'); 
/** 
* UniqueCounter Model 
* 
*/ 
class UniqueCounter extends AppModel { 

/** 
* Primary key field 
* 
* @var string 
*/ 
    public $primaryKey = 'counter'; 

/** 
* Validation rules 
* 
* @var array 
*/ 
    public $validate = array(
     'counter' => array(
      'numeric' => array(
       'rule' => array('numeric'), 
       //'message' => 'Your custom message here', 
       //'allowEmpty' => false, 
       //'required' => false, 
       //'last' => false, // Stop validation after this rule 
       //'on' => 'create', // Limit validation to 'create' or 'update' operations 
      ), 
     ), 
    ); 

    public function get_unique_counter(){ 
     $data=array(); 
     $data['UniqueCounter']['counter']=0; 
     $data['UniqueCounter']['field']=1; 

     if($this->save($data)){ 
      $new_id=$this->getLastInsertID(); 
      $this->delete($new_id); 
      return($new_id); 
     } 
     return(-1); 
    } 
} 

Любые проверки на диапазон принадлежности результата могут быть реализованы в одной и той же функции, манипулируя полученным результатом.

2

Я некоторое время боролся с решением, а затем понял, что он не работает, если столбец имеет NULL-записи. Я переработал это со следующим кодом;

SELECT FLOOR(10000 + RAND() * 89999) AS my_tracker FROM Table1 WHERE "tracker" NOT IN (SELECT tracker FROM Table1 WHERE tracker IS NOT NULL) LIMIT 1 

Fiddle here; http://sqlfiddle.com/#!2/620de1/1

Надежда его полезно :)

0

Создать уникальный индекс на поле вы хотите уникальный случайный #

Затем запустите

Update IGNORE Table Set RandomUniqueIntegerField=FLOOR(RAND() * 1000000);

Смежные вопросы