Cơ hội thiết kế lại cơ sở dữ liệu: Thiết kế bảng nào để sử dụng cho việc thu thập dữ liệu cảm biến này?


13

Lý lịch

Tôi có một mạng lưới khoảng 2000 cảm biến, mỗi cảm biến có khoảng 100 điểm dữ liệu mà chúng tôi thu thập trong khoảng thời gian 10 phút. Các điểm dữ liệu này thường là giá trị int, nhưng một số là chuỗi và float. Dữ liệu này nên được lưu trữ trong 90 ngày, nhiều hơn nếu có thể và vẫn hiệu quả.

Thiết kế cơ sở dữ liệu

Khi ban đầu được giao nhiệm vụ với dự án này, tôi đã viết một ứng dụng C # viết các tệp được phân tách bằng dấu phẩy cho mỗi cảm biến. Vào thời điểm đó không có nhiều, khi ai đó muốn xem xét các xu hướng, chúng tôi sẽ mở csv trong Excel và vẽ biểu đồ khi cần thiết.

Mọi thứ phát triển và chúng tôi chuyển sang cơ sở dữ liệu MySQL. Tôi đã tạo một bảng cho mỗi cảm biến (vâng tôi biết, rất nhiều bảng!); nó đã hoạt động tốt, nhưng nó có một số hạn chế. Với rất nhiều bảng, rõ ràng không thể viết một truy vấn sẽ tìm thấy dữ liệu trong số tất cả các cảm biến khi tìm kiếm một giá trị cụ thể.

Đối với phiên bản tiếp theo, tôi chuyển sang Microsoft SQL Server Express và đặt tất cả dữ liệu cảm biến vào một bảng lớn. Điều này cũng hoạt động và cho phép chúng tôi thực hiện các truy vấn để tìm giá trị trong số tất cả các cảm biến được quan tâm. Tuy nhiên, tôi đã chạy vào giới hạn 10 GB cho phiên bản Express và đã quyết định chuyển trở lại MySQL thay vì đầu tư vào SQL Server Standard.

Câu hỏi

Tôi hài lòng với hiệu suất và khả năng mở rộng của MySQL, nhưng không chắc chắn nếu tuân theo cách tiếp cận tất cả dữ liệu trong một bảng là tốt nhất. 10GB trong một bảng dường như đang yêu cầu một thiết kế khác. Tôi nên đề cập rằng nhu cầu truy vấn dữ liệu để vẽ đồ thị vẫn còn đó và tôi lo ngại rằng sẽ có vấn đề về hiệu năng đối với truy vấn mà đồ thị, ví dụ, dữ liệu nhiệt độ cho một cảm biến trong 90 ngày. (Nói cách khác, biểu đồ phải là thứ gì đó được sản xuất nhanh chóng, không cần chờ SQL sắp xếp qua hàng đống dữ liệu chỉ để cách ly cảm biến quan tâm.)

Tôi có nên chia bảng này theo một cách nào đó để tăng hiệu suất? Hoặc không phải là bất thường khi có một bàn lớn như vậy?

Tôi có các chỉ mục trên các cột Cảm biến và Dấu thời gian, đây là ranh giới xác định cho bất kỳ truy vấn nào. (tức là lấy dữ liệu cho cảm biến X từ thời điểm A đến thời điểm B).

Tôi đã đọc một chút về shending và phân vùng, nhưng không cảm thấy những điều đó là phù hợp trong trường hợp này.


Biên tập:

Dựa trên các nhận xét và câu trả lời cho đến nay, một số thông tin bổ sung có thể hữu ích:

Không lưu trữ không xác định: Hiện tại tôi không lưu trữ dữ liệu trong 90 ngày qua. Hàng ngày, tôi chạy một truy vấn loại bỏ dữ liệu cũ hơn 90 ngày. Nếu nó trở nên quan trọng trong tương lai, tôi sẽ lưu trữ nhiều hơn, nhưng bây giờ nó là đủ. Điều này giúp giữ kích thước trong kiểm tra và hiệu suất cao (er).

Loại động cơ: Việc triển khai MySQL ban đầu đã sử dụng MyISAM. Khi tạo các bảng lần này để triển khai mới (một bảng dữ liệu thay vì nhiều bảng), chúng đã được mặc định là InnoDB. Tôi không tin rằng tôi có một yêu cầu cho cái này hay cái khác.

Chuẩn hóa: Tất nhiên có các bảng khác ngoài bảng thu thập dữ liệu. Các bảng hỗ trợ này lưu trữ những thứ như thông tin mạng cho các cảm biến, thông tin đăng nhập cho người dùng, v.v. Không có gì nhiều để bình thường hóa (theo như tôi biết). Lý do bảng dữ liệu có rất nhiều cột là có nhiều biến từ mỗi cảm biến. (Nhiều nhiệt độ, mức ánh sáng, áp suất không khí, v.v.) Bình thường hóa với tôi có nghĩa là không có dữ liệu dư thừa hoặc các nhóm lặp lại. (Ít nhất là cho 1NF.) Đối với một cảm biến nhất định, việc lưu trữ tất cả các giá trị tại một thời điểm cụ thể yêu cầu một hàng dữ liệu và không có mối quan hệ 1: N nào liên quan ở đó (mà tôi thấy).

Tôi có thể tách bảng theo chức năng, tạo (ví dụ) tất cả các giá trị liên quan đến nhiệt độ trong một bảng và tất cả các giá trị liên quan đến áp suất không khí trong một bảng khác. Mặc dù điều này có thể cải thiện hiệu quả cho ai đó thực hiện truy vấn chỉ có nhiệt độ, tôi vẫn phải chèn tất cả dữ liệu cùng một lúc. Tuy nhiên, mức tăng hiệu quả có thể đáng giá cho các hoạt động CHỌN. Rõ ràng tôi sẽ tốt hơn khi tách bảng theo chiều dọc dựa trên tần suất người dùng yêu cầu dữ liệu. Có lẽ đây là tất cả những gì tôi nên làm. Tôi cho rằng khi đặt câu hỏi của tôi, tôi đang tìm kiếm xác nhận rằng làm điều này sẽ có giá trị.


Chỉnh sửa 2:

Sử dụng dữ liệu: Cuối cùng, phần lớn dữ liệu không bao giờ được xem xét hoặc cần thiết, bởi vì chúng tôi thường chỉ tập trung vào các mục có vấn đề. Nhưng trong nỗ lực tìm kiếm các vấn đề, chúng tôi sử dụng các công cụ khác nhau để tìm kiếm dữ liệu và xác định mục nào để phóng to.

Ví dụ: chúng tôi nhận thấy mối tương quan giữa giá trị sử dụng bộ nhớ (chương trình phần mềm độc quyền dành riêng cho khách hàng) và khởi động lại / sự cố. Một trong những điểm dữ liệu tôi thu thập liên quan đến việc sử dụng bộ nhớ này và tôi có thể xem dữ liệu lịch sử để cho thấy các thiết bị trở nên không ổn định sau khi vượt quá mức sử dụng bộ nhớ cụ thể. Hôm nay, đối với tập hợp con của các thiết bị chạy phần mềm này, tôi kiểm tra giá trị này và đưa ra lệnh khởi động lại nếu nó quá cao. Cho đến khi điều này được phát hiện, tôi không nghĩ việc thu thập dữ liệu này có giá trị.

Vì lý do này, tôi đã duy trì rằng khoảng 100 điểm dữ liệu được thu thập và lưu trữ, ngay cả khi giá trị có thể nghi ngờ. Nhưng trong việc sử dụng hàng ngày thông thường, người dùng thường kiểm tra có lẽ hàng tá các thông số này. Nếu người dùng quan tâm đến một khu vực địa lý cụ thể, anh ta có thể (sử dụng phần mềm) tạo biểu đồ hoặc bảng tính dữ liệu cho khoảng vài chục cảm biến. Không có gì lạ khi nhìn vào biểu đồ 30 ngày với hai hoặc ba đường kẻ ô hiển thị những thứ như nhiệt độ, áp suất không khí và mức độ ánh sáng. Làm điều này sẽ chạy một truy vấn tương tự như sau:

SELECT sensor_id, location, data_timestamp, temp1, air1, light1
FROM data
WHERE data_timestamp >= '2012-02-01'
AND sensor_id IN (1, 2, 3);

(Trong phiên bản MySQL gốc, trong đó mỗi cảm biến có bảng riêng, ba truy vấn riêng sẽ được đưa ra, nhưng kết quả được kết hợp trong phần mềm để tạo biểu đồ.)

Bởi vì databảng chứa rất nhiều hàng (~ 10 triệu), mặc dù có các chỉ số trên iddata_timestamp, hiệu suất kém hơn đáng kể so với kịch bản nhiều bảng (4500 hàng được trả về trong 9 giây so với chưa đến một giây với ví dụ này). Khả năng tìm cảm biến nào đáp ứng các tiêu chí nhất định thực tế bằng không trong lược đồ nhiều bảng và do đó, lý do để chuyển sang một bảng duy nhất.

Loại truy vấn này có thể được thực hiện bởi nhiều người dùng liên tiếp khi họ chọn các nhóm dữ liệu khác nhau và so sánh các biểu đồ từ mỗi kết quả. Có thể khá bực bội khi chờ gần 10 giây cho mỗi biểu đồ hoặc bảng tính.

Dữ liệu bị loại bỏ sau 90 ngày. Nó có thể được lưu trữ nhưng hiện tại nó không phải là một yêu cầu.

Hy vọng thông tin này sẽ giúp hiển thị đầy đủ hơn cách thức dữ liệu được sử dụng sau khi thu thập và lưu trữ.


Đối với câu hỏi này để có câu trả lời đúng , có lẽ bạn nên mở rộng về cách dữ liệu thực sự được sử dụng. Bạn đang đi trước đường cong về độ sâu của thông tin bạn đã cung cấp cho đến nay nhưng bạn có thể đang hỏi câu hỏi của bạn từ góc độ sai.
Mark Storey-Smith

Điểm hay, @Mark, tôi cũng sẽ giải thích về điều đó. Tôi đã cố gắng không có một câu hỏi quá dài vì sợ nó sẽ áp đảo.
JYelton

Câu trả lời:


5

Bạn nên suy nghĩ về việc phân vùng bảng vì một lý do lớn.

Tất cả các chỉ mục bạn có trên một bảng khổng lồ, thậm chí chỉ một chỉ mục, có thể tạo ra rất nhiều tải CPU và I / O của đĩa chỉ để thực hiện bảo trì chỉ mục khi thực hiện INSERT, UPDATE và DELETE.

Tôi đã viết một bài đăng trước đó vào ngày 7 tháng 10 năm 2011 về lý do tại sao Bảng phân vùng sẽ là một trợ giúp lớn. Đây là một đoạn trích từ bài viết trước đây của tôi:

Phân vùng dữ liệu sẽ phục vụ cho nhóm dữ liệu hợp lý và gắn kết trong cùng một lớp. Hiệu suất tìm kiếm từng phân vùng không cần phải được xem xét chính miễn là dữ liệu được nhóm chính xác. Một khi bạn đã đạt được phân vùng hợp lý, sau đó tập trung vào thời gian tìm kiếm. Nếu bạn chỉ tách dữ liệu bằng id, có thể nhiều hàng dữ liệu có thể không bao giờ được truy cập để đọc hoặc ghi. Bây giờ, đó phải là một sự cân nhắc chính: Xác định vị trí tất cả các id thường xuyên truy cập và phân vùng theo đó. Tất cả các id ít được truy cập thường nằm trong một bảng lưu trữ lớn vẫn có thể truy cập được bằng cách tra cứu chỉ mục cho truy vấn 'một lần trong một mặt trăng xanh'.

Bạn có thể đọc toàn bộ bài viết của tôi sau này về điều này.

Để cắt quyền theo đuổi, bạn cần nghiên cứu và tìm ra dữ liệu nào hiếm khi được sử dụng trong bảng 10GB của bạn. Dữ liệu đó nên được đặt trong bảng lưu trữ có thể truy cập dễ dàng nếu bạn cần truy vấn adhoc cho bản chất lịch sử. Di chuyển lưu trữ đó từ 10 GB, theo sau là OPTIMIZE TABLEtrên bảng 10 GB, có thể dẫn đến Tập làm việc nhanh hơn để chạy CHỌN, CHERTN, CẬP NHẬT và XÓA. Thậm chí DDL sẽ đi nhanh hơn trên Bộ làm việc 2 GB so với bảng 10 GB.

CẬP NHẬT 2012/02/24 16:19 EDT

Hai điểm cần xem xét

  1. Từ nhận xét của bạn, có vẻ như bình thường hóa là những gì bạn có thể cần.
  2. Bạn có thể cần di chuyển mọi thứ trên 90 ngày tuổi vào một bảng lưu trữ nhưng vẫn truy cập vào kho lưu trữ và bộ làm việc cùng một lúc. Nếu dữ liệu của bạn là tất cả MyISAM, tôi khuyên bạn nên sử dụng công cụ lưu trữ MERGE. Trước tiên, bạn tạo bản đồ bảng MERGE một lần để kết hợp bảng MyISAM được thiết lập hoạt động và bảng MyISAM lưu trữ. Bạn sẽ giữ dữ liệu dưới 91 ngày trong một bảng MyISAM và cuộn lại bất kỳ dữ liệu nào trên 90 ngày vào kho lưu trữ. Bạn sẽ chỉ truy vấn bản đồ bảng MERGE.

Đây là hai bài viết tôi đã làm về cách sử dụng nó:

Đây là một bài viết bổ sung tôi đã thực hiện trên các bảng có rất nhiều cột

Quá nhiều cột trong MySQL


Có những cột ít thường xuyên hơn, nhưng tất cả các cảm biến đều nhận được cùng một tỷ lệ chú ý. Vì vậy, tôi có thể tưởng tượng việc chia bảng theo chiều dọc sẽ là lợi thế. Ví dụ: bảng 20 cột (thường xuyên truy cập) và bảng 80 cột (truy cập không thường xuyên). Tôi không chắc đây là điều tương tự như phân vùng.
JYelton

Cảm ơn đã chỉnh sửa. Tôi đọc bài viết của bạn về "Quá nhiều cột trong MySQL." Tôi sẽ chỉnh sửa câu hỏi của tôi với một số điểm bổ sung có thể hữu ích.
JYelton

5

Thật thú vị ... Nếu tất cả các cảm biến tạo ra cùng một loại dữ liệu, sẽ rất hợp lý khi đặt tất cả chúng vào cùng một bảng, nhưng với lượng dữ liệu đó, tôi có thể thấy tại sao bạn lại lo lắng về hiệu suất.

Là 90 ngày thời gian thông thường mà bạn tạo ra một biểu đồ cho? Nếu vậy, bạn có thể có hai bảng: bảng dữ liệu cảm biến chính lưu trữ dữ liệu từ 90 (hoặc hơn một chút nếu bạn muốn một chút chùng) ngày trước cho đến ngày hôm nay và mọi thứ cũ hơn trong bảng lưu trữ. Điều đó có thể giúp giảm kích thước của bảng mà các báo cáo được bắt đầu tạo ra và hy vọng phần lớn 10 GB dữ liệu của bạn sẽ nằm trong bảng lưu trữ chứ không phải trong bảng chính. Công việc lưu trữ có thể được lên kế hoạch để chạy hàng đêm.

Cũng có thể xem xét việc xây dựng cơ sở dữ liệu báo cáo riêng biệt lưu trữ dữ liệu theo cấu trúc tốt hơn để tạo báo cáo từ (các bảng được thiết kế để phù hợp hơn với những gì bạn đang truy vấn, và có thể tính toán trước và tổng hợp các giá trị mà sẽ mất nhiều thời gian để tạo, nếu có thể) và nhập lại từ cơ sở dữ liệu chính một cách thường xuyên (chẳng hạn như hàng đêm). Tất nhiên, nếu bạn cần các báo cáo được tạo từ dữ liệu cập nhật từng phút, điều này có thể không hoạt động tốt.


Lưu trữ bất cứ điều gì trong 90 ngày qua tại thời điểm này là không cần thiết nhưng sẽ tốt đẹp. Tôi đồng ý tốt nhất để lưu trữ trong một bảng "lưu trữ". Đồ thị và phân tích dữ liệu nằm trong khoảng từ vài giờ đến 90 ngày. Hầu hết các yêu cầu vẽ đồ thị chỉ sử dụng dữ liệu trong tuần qua hoặc lâu hơn, nhưng đồ thị 90 ngày là phổ biến. Công ty chúng tôi chưa (chưa) yêu cầu báo cáo dài hơn.
JYelton

@JYelton: Bạn có thể có nhiều tầng trong cách tiếp cận này như bạn muốn. Bảng mới nhất có thể chỉ có từ hôm nay. Bảng tiếp theo có thể có từ hôm nay đến 2 tuần trước. Bảng tiếp theo có thể có từ Hôm nay đến 90 ngày trước. Bảng cuối cùng có thể MỌI thứ.
Thất vọngWithFormsDesigner

Nếu tôi hiểu bạn một cách chính xác, bạn đang nói để sao chép bảng, nhưng với các khoảng thời gian khác nhau. Vì vậy, nếu ai đó yêu cầu báo cáo 7 ngày, một bảng chỉ quay lại một tuần sẽ được sử dụng. Nếu sau đó chúng mở rộng lên 8 ngày, bảng lớn nhất tiếp theo (ví dụ 30 ngày) sẽ được sử dụng? Điều này chắc chắn sẽ cải thiện tốc độ của các truy vấn thời gian ngắn hơn, nhưng với chi phí lưu trữ (giá rẻ) và logic lập trình để đối phó với các bảng được xếp lớp (không rẻ bằng).
JYelton

@JYelton: Vâng, tôi nghĩ bạn hiểu nó một cách chính xác. Nếu các khoảng thời gian truy vấn là tiêu chuẩn (hôm nay - 1 ngày, hôm nay - 7 ngày, hôm nay - 30 ngày, hôm nay - 90 ngày) thì tôi không nghĩ sẽ quá khó vì bạn sẽ luôn biết bảng nào đánh. Nếu các phạm vi thời gian có thể có độ dài khác nhau trong đó bắt đầu của phạm vi có thể không phải là ngày hiện tại, thì bạn đã đúng logic để thực hiện sẽ gặp khó khăn và các truy vấn mà các bảng chéo có thể tốn kém với các hoạt động UNION trên nhiều bảng.
Thất vọngWithFormsDesigner
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.