Việc chia bảng 'người dùng cho mục đích xác thực có phải là một ý tưởng hay không?


8

Giả sử tôi có một bảng người dùng trong trang web của mình trong đó có khoảng 2-3 triệu người dùng (bản ghi) trong bảng.

Để tăng tốc quá trình đăng nhập của tôi, đó có phải là một cách tiếp cận tốt để phân chia bảng người dùng của tôi, một cho thông tin của họ và một cho đăng nhập của họ.

Nếu chúng ta có thể chạy một truy vấn tương tự như truy vấn bên dưới từ một bảng:

select username,password from users where username=`test` AND password=****

Có cần phải phân tách nó không và điều này có làm tăng tốc quá trình đăng nhập trang web của tôi không?


1
Thêm điều này chỉ là một nhận xét vì nó không phải là một câu trả lời trực tiếp cho câu hỏi của bạn. Có thể đây là những gì bạn đang làm ngoài truy vấn mẫu của mình nhưng việc lưu trữ mật khẩu thực tế trong cơ sở dữ liệu của bạn là một thực tế rất xấu. Bạn muốn lưu trữ chúng dưới dạng có và sau đó truy vấn như nơi password_hash = hash ($
user EntryedPassword

@atxdba Tôi thực sự đã băm chúng, nhưng ở đây tôi chỉ đưa ra một ví dụ.
ALH

Câu trả lời:


10

IMHO Bạn không cần phải chia nhỏ nó ra. Tuy nhiên, nó sẽ được tốt đẹp để lưu trữ nó.

Nếu usersbảng sử dụng MyISAM Storage Engine, bạn có một lợi thế tốt.

Vì MyISAM chỉ lưu trữ các chỉ mục, bạn có thể làm hai việc

  • Bạn có thể tạo bộ đệm khóa tùy chỉnh chỉ để tải chỉ mục MyISAM cho usersbảng
  • Bạn có thể lập chỉ mục tên người dùng và mật khẩu để buộc truy vấn chỉ nhấn vào bộ đệm khóa tùy chỉnh đó

Đảm bảo các chỉ mục sau tồn tại cho users

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);

Có hai (2) lý do chính cho hai chỉ số

LÝ DO cho chỉ số # 1

Chỉ mục username_ndxngăn tên người dùng có nhiều mật khẩu, cũng như ngăn nhiều người dùng có cùng tên

LÝ DO cho chỉ số # 2

Các chỉ số username_password_ndxcung cấp một chỉ số bao gồm . Do đó, truy vấn của bạn sẽ tra cứu tên người dùng và mật khẩu chỉ trong bộ đệm MyISAM tùy chỉnh, thay vì kiểm tra bảng.

Liên kết khác về các nguyên tắc của chỉ số bao phủ

Điều tiếp theo là thực sự tạo bộ đệm khóa tùy chỉnh đó. Dưới đây là các lệnh để tạo bộ đệm chính 8 MB và tải bộ đệm chính dành riêng đó (Ví dụ: Nếu bảng là mydb.users):

SET GLOBAL authentication_cache.key_buffer_size = 1024 * 1024 * 8;
CACHE INDEX mydb.users IN authentication_cache;
LOAD INDEX INTO CACHE mydb.users;

Bạn nên đặt ba dòng này trong tệp /var/lib/mysql/startup.sql

Thêm phần này vào /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/startup.sql

Điều này sẽ tải bộ đệm mỗi khi khởi động mysql

Hãy thử một lần !!!

CẬP NHẬT 2011-12-30 17:25 EDT

Nếu bạn muốn lấy kích thước chính xác để đặt bộ đệm, hãy sử dụng truy vấn sau:

SELECT CONCAT('1024 * 1024 * ',ROUND(index_length/power(1024,2))) RecommendedCacheSize
FROM information_schema.tables WHERE table_name='users';

CẬP NHẬT 2011-12-30 23:21 EDT

Đây là một phương pháp dựa trên InnoDB

Bạn vẫn cần các chỉ mục

ALTER TABLE users ADD UNIQUE INDEX username_ndx (username);
ALTER TABLE users ADD UNIQUE INDEX username_password_ndx (username,password);

Bạn phải đảm bảo Bộ đệm InnoDB có tên người dùng và mật khẩu khả dụng. Bạn có thể phải dùng đến việc quét toàn bộ chỉ mục khi khởi động mysql:

Bước 1) Tạo ReadUserPass.sql

echo "select username,password from users;" > /var/lib/mysql/ReadUserPass.sql

Bước 2) Thêm tập lệnh đó vào /etc/my.cnf

[mysqld]
init-file=/var/lib/mysql/ReadUserPass.sql

Bước 3) Thực hiện một trong những điều sau đây

  • $ service mysql restart
  • mysql> source /var/lib/mysql/ReadUserPass.sql

Vì cả hai cột này (tên người dùng và mật khẩu) đều nằm trong username_password_ndx, tất cả các trang chỉ mục tạo nên chỉ mục này được tải lại vào Nhóm đệm của InnoDB. Điều này là cần thiết bởi vì có khả năng của các trang chỉ mục được tuôn ra. Để giảm thiểu điều đó xảy ra, hãy tăng Kích thước vùng đệm và khởi động lại mysql (một lần).


Trên thực tế tôi sử dụng công cụ lưu trữ InnoDB, nhưng tôi nghĩ rằng quá trình bộ nhớ cache sẽ ổn với nó, phải không @RolandoMyQueryDBA?
ALH

Không. Các bước trong câu trả lời của tôi chỉ là MyISAM.
RolandoMySQLDBA

Nếu usersbảng có liên quan đến giao dịch, thì tôi cần gửi câu trả lời khác chỉ dựa trên InnoDB.
RolandoMySQLDBA

Xin lỗi tôi đã không đề cập đến điều đó, tôi không biết họ sẽ có những cách tiếp cận khác nhau!
ALH

Tôi đã trả lời dựa trên MyISAM vì tôi muốn bảng người dùng được lưu trong bộ đệm chính của nó.
RolandoMySQLDBA

5

Một bảng gồm vài triệu hàng không cần phải tách ra. Điều chỉnh hiệu suất nên được thực hiện thông qua các chỉ mục. MySpace có hàng trăm triệu tài khoản được liệt kê trong một bảng duy nhất và hiệu suất trên bảng đó là tốt. (Tôi là một DBA cho MySpace ở độ cao sử dụng của họ.) Bảng trong trường hợp đó có thể rộng 80-90 byte (có thể hơn một chút).


Ơ, kích thước RAM như thế nào?
Chibueze Opata

3

Bạn có thực sự có 2 triệu người dùng? Trừ khi bạn đã có vấn đề này hoặc chắc chắn rằng bạn sẽ làm được, bạn sẽ tối ưu hóa trước thời hạn. Thêm một chỉ mục ghép trên các trường đăng nhập và mật khẩu và được thực hiện với nó. Đừng tối ưu hóa trừ khi bạn biết bạn thực sự có vấn đề cần giải quyết. Tôi chắc chắn bạn có vấn đề lớn hơn để giải quyết.


1
Ý bạn là gì khi "bạn chắc chắn tôi có vấn đề lớn hơn cần giải quyết"?
ALH

1
Sẽ không có ý nghĩa gì khi giải quyết vấn đề khi chúng ta biết trong tương lai gần chúng ta sẽ gặp rất nhiều vấn đề. Xử lý sự cố này là một vấn đề đau đầu khi có rất nhiều dữ liệu trong bảng! -1 cho bạn.
ALH

2
Quan điểm của tôi là gấp đôi ... không tối ưu hóa trước khi bạn phải & 2 triệu hồ sơ không nhiều lắm. Một chỉ số sẽ rất nhiều.
Aaron Brown

2

Nếu bạn sử dụng Mysql 5.1 trở lên, bạn có thể thử phân vùng bảng của mình.
Đối với câu hỏi của bạn về việc liệu nó có tăng tốc quá trình đăng nhập hay không, nó phụ thuộc vào phần còn lại của quy trình đăng nhập trông như thế nào (ví dụ: nếu truy vấn của bạn bây giờ mất 0,05 giây và phần còn lại của mã mất 20 giây, tôi muốn thay thế lại. nghĩ toàn bộ thói quen ...).
Ngoài ra, bất kể sử dụng phân vùng, đừng quên thêm chỉ mục như RolandoMyQueryDBA đã chỉ ra.


Gọi tốt để xác định nguyên nhân thực sự của một vấn đề hiệu suất trước khi tối ưu hóa. Nó thường không phải là nơi chúng ta nghĩ rằng nó là. Bằng chứng điều chỉnh dựa trên là cách để đi!
Stuart Woodward
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.