2010-01-31 31 views
5

Liệu hỗ trợ SQLite seeding chức năng RANDOM() theo cùng một cách MySQL thực hiện với RAND()?Seeding SQLite RANDOM()

$query = "SELECT * FROM table ORDER BY RAND(" . date('Ymd') . ") LIMIT 1;"; 

Từ Manual MySQL về RAND(N):

Nếu một đối số hằng số nguyên N là chỉ định, nó được sử dụng như giá trị hạt giống , trong đó sản xuất một chuỗi lặp lại các giá trị cột . Trong ví dụ sau , lưu ý rằng các chuỗi giá trị được tạo bởi RAND (3) giống nhau ở cả hai nơi mà xảy ra.

Nếu không, có cách nào để lưu trữ cùng một hiệu ứng chỉ bằng một truy vấn không?

Trả lời

3

Nếu bạn cần một trật tự giả ngẫu nhiên, bạn có thể làm một cái gì đó như thế này (PHP):

$seed = md5(mt_rand()); 
$prng = ('0.' . str_replace(array('0', 'a', 'b', 'c', 'd', 'e', 'f'), array('7', '3', '1', '5', '9', '8', '4'), $seed)) * 1; 
$query = 'SELECT id, name FROM table ORDER BY (substr(id * ' . $prng . ', length(id) + 2)'; 

Thêm vào đó, bạn có thể đặt $ hạt giống với giá trị được xác định trước và luôn nhận được kết quả tương tự.

Tôi đã học được mẹo này từ đồng nghiệp của tôi http://steamcooker.blogspot.com/

+0

Bạn có thể giải thích giải pháp này không? – Luda

+0

Thật không may điều này không quy mô rất tốt cho các bảng lớn. –

+0

Luda, xin lỗi vì đã không trả lời kịp thời. http://stackoverflow.com/a/24511461/296520 là giải thích tốt về những gì đang xảy ra ở đó. – jankkhvej

10

Có một cái nhìn tại sqlite3_randomness() chức năng:

SQLite chứa một chất lượng cao giả ngẫu nhiên số máy phát điện (PRNG) được sử dụng để chọn ROWIDs ngẫu nhiên khi chèn kỷ lục mới vào một bảng mà đã sử dụng khả năng lớn nhất ROWID. PRNG cũng được sử dụng cho các hàm SQL ngẫu nhiên() và randomblob().

...

Lần đầu tiên thói quen này được gọi (bên trong hoặc bởi ứng dụng) PRNG là hạt sử dụng ngẫu nhiên thu được từ phương pháp xRandomness của sqlite3_vfs mặc định đối tượng. Trên tất cả các lời gọi tiếp theo, giả ngẫu nhiên được tạo ra trong nội bộ và không truy đòi vào phương thức sqlite3_vfs xRandomness.

Nhìn vào nguồn của phương thức xRandomness này, bạn có thể thấy nó đọc từ /dev/urandom trên Unix. Trên Windows, nó chỉ trả về giá trị trả về của một số hàm thời gian. Vì vậy, có vẻ như tùy chọn duy nhất của bạn là bắt đầu tấn công vào mã nguồn SQLite.

Các vấn đề liên quan