Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

MySQL và NoSQL:Giúp tôi chọn đúng

Bạn nên đọc phần sau và tìm hiểu một chút về ưu điểm của bảng innodb được thiết kế tốt và cách tốt nhất để sử dụng các chỉ mục được phân nhóm - chỉ khả dụng với innodb!

http://dev.mysql.com/doc /refman/5.0/en/innodb-index-types.html

http:// www. xaprb.com/blog/2006/07/04/how-to-exploit-mysql-index-optimizations/

sau đó thiết kế hệ thống của bạn một cái gì đó theo dòng của ví dụ đơn giản sau:

Lược đồ mẫu (đơn giản hóa)

Các tính năng quan trọng là các bảng sử dụng công cụ innodb và khóa chính cho bảng chủ đề không còn là một khóa auto_increoring đơn lẻ mà là một cụm tổng hợp dựa trên sự kết hợp của forum_id và thread_id. ví dụ:

threads - primary key (forum_id, thread_id)

forum_id    thread_id
========    =========
1                   1
1                   2
1                   3
1                 ...
1             2058300  
2                   1
2                   2
2                   3
2                  ...
2              2352141
...

Mỗi hàng diễn đàn bao gồm một bộ đếm được gọi là next_thread_id (unsigned int) được duy trì bởi một trình kích hoạt và tăng lên mỗi khi một chủ đề được thêm vào một diễn đàn nhất định. Điều này cũng có nghĩa là chúng tôi có thể lưu trữ 4 tỷ chủ đề trên mỗi diễn đàn thay vì tổng cộng 4 tỷ chủ đề nếu sử dụng một khóa chính auto_increment duy nhất cho thread_id.

forum_id    title   next_thread_id
========    =====   ==============
1          forum 1        2058300
2          forum 2        2352141
3          forum 3        2482805
4          forum 4        3740957
...
64        forum 64       3243097
65        forum 65      15000000 -- ooh a big one
66        forum 66       5038900
67        forum 67       4449764
...
247      forum 247            0 -- still loading data for half the forums !
248      forum 248            0
249      forum 249            0
250      forum 250            0

Nhược điểm của việc sử dụng khóa tổng hợp là bạn không còn có thể chỉ chọn một chủ đề bằng một giá trị khóa duy nhất như sau:

select * from threads where thread_id = y;

bạn phải làm:

select * from threads where forum_id = x and thread_id = y;

Tuy nhiên, mã ứng dụng của bạn nên biết người dùng đang duyệt diễn đàn nào để không khó thực hiện chính xác - lưu trữ forum_id hiện đang xem trong trường biến phiên hoặc trường biểu mẫu ẩn, v.v.

Đây là giản đồ đơn giản:

drop table if exists forums;
create table forums
(
forum_id smallint unsigned not null auto_increment primary key,
title varchar(255) unique not null,
next_thread_id int unsigned not null default 0 -- count of threads in each forum
)engine=innodb;


drop table if exists threads;
create table threads
(
forum_id smallint unsigned not null,
thread_id int unsigned not null default 0,
reply_count int unsigned not null default 0,
hash char(32) not null,
created_date datetime not null,
primary key (forum_id, thread_id, reply_count) -- composite clustered index
)engine=innodb;

delimiter #

create trigger threads_before_ins_trig before insert on threads
for each row
begin
declare v_id int unsigned default 0;

  select next_thread_id + 1 into v_id from forums where forum_id = new.forum_id;
  set new.thread_id = v_id;
  update forums set next_thread_id = v_id where forum_id = new.forum_id;
end#

delimiter ;

Bạn có thể nhận thấy rằng tôi đã bao gồm reply_count như một phần của khóa chính, điều này hơi kỳ lạ vì bản thân tổ hợp (forum_id, thread_id) là duy nhất. Đây chỉ là một tối ưu hóa chỉ mục giúp tiết kiệm một số I / O khi các truy vấn sử dụng reply_count được thực thi. Vui lòng tham khảo 2 liên kết ở trên để biết thêm thông tin về điều này.

Truy vấn mẫu

Tôi vẫn đang tải dữ liệu vào các bảng mẫu của mình và cho đến nay tôi đã tải được khoảng. 500 triệu hàng (nhiều hơn một nửa so với hệ thống của bạn). Khi quá trình tải hoàn tất, tôi dự kiến ​​sẽ có khoảng:

250 forums * 5 million threads = 1250 000 000 (1.2 billion rows)

Tôi đã cố tình tạo một số diễn đàn chứa hơn 5 triệu chủ đề, ví dụ, diễn đàn 65 có 15 triệu chủ đề:

forum_id    title   next_thread_id
========    =====   ==============
65        forum 65      15000000 -- ooh a big one

Thời gian chạy truy vấn

select sum(next_thread_id) from forums;

sum(next_thread_id)
===================
539,155,433 (500 million threads so far and still growing...)

dưới innodb, việc tổng hợp next_thread_ids để đưa ra tổng số luồng nhanh hơn nhiều so với thông thường:

select count(*) from threads;

Diễn đàn 65 có bao nhiêu chủ đề:

select next_thread_id from forums where forum_id = 65

next_thread_id
==============
15,000,000 (15 million)

một lần nữa, điều này nhanh hơn bình thường:

select count(*) from threads where forum_id = 65

Được rồi, bây giờ chúng ta biết rằng chúng ta có khoảng 500 triệu chủ đề cho đến nay và diễn đàn 65 có 15 triệu chủ đề - hãy xem lược đồ hoạt động như thế nào :)

select forum_id, thread_id from threads where forum_id = 65 and reply_count > 64 order by thread_id desc limit 32;

runtime = 0.022 secs

select forum_id, thread_id from threads where forum_id = 65 and reply_count > 1 order by thread_id desc limit 10000, 100;

runtime = 0.027 secs

Tôi trông khá hiệu quả - vì vậy đó là một bảng duy nhất có hơn 500 triệu hàng (và đang tăng lên) với truy vấn bao gồm 15 triệu hàng trong 0,02 giây (khi đang tải!)

Tối ưu hơn nữa

Chúng sẽ bao gồm:

  • phân vùng theo phạm vi

  • sharding

  • ném tiền và phần cứng vào nó

vv ...

hy vọng bạn thấy câu trả lời này hữu ích :)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách xem trạng thái và biến hệ thống trong MySQL Workbench bằng GUI

  2. Di chuyển Cơ sở dữ liệu MySQL từ CloudSQL sang AWS RDS

  3. Cách thêm ngày vào ngày trong MySQL

  4. Cách đổi tên cơ sở dữ liệu trong MySQL

  5. PHP PDO so với mysql_connect bình thường