Cơ sở dữ liệu quan hệ đạt được gì bằng cách đặt loại dữ liệu được xác định trước cho mỗi cột?


44

Tôi đang làm việc với cơ sở dữ liệu SQL ngay bây giờ và điều này luôn khiến tôi tò mò, nhưng các tìm kiếm của Google không bật lên nhiều: Tại sao các loại dữ liệu nghiêm ngặt?

Tôi hiểu lý do tại sao bạn có một vài loại dữ liệu khác nhau, ví dụ như sự khác biệt giữa dữ liệu văn bản nhị phân và văn bản thuần túy là quan trọng . Thay vì lưu trữ dữ liệu nhị phân 1 và 0 dưới dạng bản rõ, giờ đây tôi hiểu rằng việc lưu trữ dữ liệu nhị phân dưới dạng định dạng của mình sẽ hiệu quả hơn.

Nhưng điều tôi không hiểu là lợi ích của việc có nhiều loại dữ liệu khác nhau là gì:

  • Tại sao mediumtext, longtexttext?
  • Tại sao decimal, floatint?
  • Vân vân.

Lợi ích của việc nói với cơ sở dữ liệu là "Sẽ chỉ có 256 byte dữ liệu văn bản thuần túy trong các mục vào cột này." hoặc "Cột này có thể có các mục nhập văn bản lên tới 16.777.215 byte"?

Nó có phải là một lợi ích hiệu suất? Nếu vậy, tại sao biết kích thước của mục trước khi thực hiện trợ giúp tay? Hay đúng hơn là một cái gì đó khác hoàn toàn?


2
Tôi nghĩ rằng câu hỏi này đã tồn tại ở đây, nhưng tôi đã tìm kiếm trang web và không tìm thấy bất cứ điều gì hữu ích.
john doe


6
Nếu bạn không có khác biệt decimal, floatintcác loại, những gì bạn mong đợi 1 / 3để làm gì? Thế còn 1.0 / 3.0? Bạn có thể tự tin rằng khi bạn chia columnAbởi columnBrằng bạn sẽ nhận được kết quả mà bạn mong đợi?
Andrew nói Phục hồi lại

2
@johndoe Tôi không nghĩ nó sẽ cần thiết, nhưng nó có thể rất thuận tiện. Giả sử bạn muốn thực thi một ràng buộc rằng hàng tồn kho của cửa hàng không thể thấp hơn 5% doanh số dự kiến ​​hàng tháng của họ. Hoặc bạn muốn đảm bảo rằng tổng ngân sách của mỗi bộ phận không quá 20% tổng ngân sách. Nó cũng có thể xuất hiện trong các cột được tính toán mà bạn muốn tính toán theo cùng một cách trong một số ứng dụng sử dụng cùng một cơ sở dữ liệu.
Andrew nói Phục hồi Monica

2
Điều đáng chú ý là SQLite không đặt loại được xác định trước cho mỗi cột : "SQLite là" không chữ ". Điều này có nghĩa là bạn có thể lưu trữ bất kỳ loại dữ liệu nào bạn muốn trong bất kỳ cột nào của bất kỳ bảng nào, bất kể kiểu dữ liệu được khai báo của cột đó. "
Thủ tướng

Câu trả lời:


50

SQL là một ngôn ngữ gõ tĩnh . Điều này có nghĩa là bạn phải biết loại biến (hoặc trường, trong trường hợp này) là gì trước khi bạn có thể sử dụng nó. Điều này trái ngược với các ngôn ngữ được gõ động, trong đó không nhất thiết phải như vậy.

Tại cốt lõi của nó, SQL được thiết kế để xác định dữ liệu ( DDL ) và dữ liệu truy cập ( DML ) trong một công cụ cơ sở dữ liệu quan hệ . Gõ tĩnh thể hiện một số lợi ích so với gõ động đối với loại hệ thống này.

  • Các chỉ mục , được sử dụng để truy cập nhanh các hồ sơ cụ thể, hoạt động thực sự tốt khi kích thước được cố định. Hãy xem xét một truy vấn sử dụng một chỉ mục, có thể có nhiều trường: nếu các kiểu dữ liệu và kích thước được biết trước, tôi có thể nhanh chóng so sánh vị từ của mình (mệnh đề WHERE hoặc tiêu chí THAM GIA) với các giá trị trong chỉ mục và tìm các bản ghi mong muốn nhanh hơn .

  • Xét hai giá trị nguyên . Trong một hệ thống kiểu động, chúng có thể có kích thước thay đổi (nghĩ Java BigIntegerhoặc các số nguyên có độ chính xác tùy ý tích hợp sẵn của Python). Nếu tôi muốn so sánh các số nguyên, trước tiên tôi cần biết độ dài bit của chúng. Đây là một khía cạnh của so sánh số nguyên phần lớn bị ẩn bởi các ngôn ngữ hiện đại, nhưng rất thực tế ở cấp độ CPU. Nếu kích thước được cố định và biết trước thời hạn, toàn bộ bước sẽ bị xóa khỏi quy trình. Một lần nữa, cơ sở dữ liệu được cho là có thể xử lý hàng trăm giao dịch nhanh nhất có thể. Tốc độ là vua.

  • SQL được thiết kế trở lại vào những năm 1970. Trong những ngày đầu của máy vi tính, bộ nhớ ở mức cao. Giới hạn dữ liệu đã giúp giữ các yêu cầu lưu trữ trong kiểm tra. Nếu một số nguyên không bao giờ tăng quá một byte, tại sao lại phân bổ thêm dung lượng cho nó? Đó là lãng phí không gian trong thời đại của bộ nhớ hạn chế. Ngay cả trong thời hiện đại, những byte bị lãng phí thêm đó có thể cộng lại và giết chết hiệu năng của bộ đệm của CPU. Hãy nhớ rằng, đây là những công cụ cơ sở dữ liệu có thể phục vụ hàng trăm giao dịch mỗi giây, không chỉ môi trường phát triển nhỏ của bạn.

  • Dọc theo dòng lưu trữ hạn chế, thật hữu ích khi có thể vừa một bản ghi trong một trang duy nhất trong bộ nhớ. Khi bạn đi qua một trang, sẽ có nhiều trang bị bỏ lỡ hơn và truy cập bộ nhớ chậm hơn. Các công cụ mới hơn có tối ưu hóa để làm cho vấn đề này ít hơn, nhưng nó vẫn còn đó. Bằng cách định cỡ dữ liệu phù hợp, bạn có thể giảm thiểu rủi ro này.

  • Moreso trong thời hiện đại, SQL được sử dụng để cắm vào các ngôn ngữ khác thông qua ORM hoặc ODBC hoặc một số lớp khác. Một số ngôn ngữ này có các quy tắc về yêu cầu các loại mạnh, tĩnh. Tốt nhất là tuân thủ các yêu cầu khắt khe hơn, vì các ngôn ngữ được gõ động có thể xử lý các loại tĩnh dễ dàng hơn so với cách khác.

  • SQL hỗ trợ gõ tĩnh vì các công cụ cơ sở dữ liệu cần nó để thực hiện, như được hiển thị ở trên.

Thật thú vị khi lưu ý rằng có các triển khai SQL không được gõ mạnh. SQLite có lẽ là ví dụ phổ biến nhất của một công cụ cơ sở dữ liệu quan hệ như vậy. Sau đó, một lần nữa, nó được thiết kế để sử dụng một luồng trên một hệ thống, do đó, mối quan tâm về hiệu năng có thể không được phát âm như trong cơ sở dữ liệu Oracle doanh nghiệp phục vụ hàng triệu yêu cầu mỗi phút.


SQLite có các kiểu dữ liệu phân biệt giữa dữ liệu số và dữ liệu văn bản, nhưng chỉ có 5 "lớp" lưu trữ dữ liệu: sqlite.org/datatype3.html
FrustratedWithFormsDesigner

1
@FrustratedWithFormsDesigner Tôi biết, nhưng nó vẫn không nghiêm ngặt như các công cụ như SQL Server, Oracle hoặc PostgreQuery.

SQL không chỉ được gõ tĩnh - do sự hiện diện của các ràng buộc kiểm tra, nó hỗ trợ hiệu quả các loại sàng lọc.
vườn

4
Mặc dù ngụ ý trong viên đạn đầu tiên Indexes, về cơ bản hơn đã nêu: Việc có một loại dữ liệu cho phép công cụ cơ sở dữ liệu hiểu được dữ liệu , để so sánh (số lớn hơn / nhỏ hơn, thời gian sớm hơn / muộn hơn, trước / sau trong bảng chữ cái), và do đó cho phép sắp xếp và truy vấn .
Basil Bourque

Vì vậy, nếu kích thước là quan trọng ... và sql cần phải biết trước ... kích thước chính xác của giao dịch "Zillion" là gì?
WernerCD

24

Thứ nhất: văn bản thuần túy là nhị phân (thậm chí không phải là các ký tự UTF8 hoặc ASCII "0" và "1" mà là các bit bật / tắt thực tế)

Điều đó nói rằng, một số lý do là:

  • Các ràng buộc về kinh doanh / thiết kế: cho phép số 7626355112 trong cột HEIGHT của bảng PERSON sẽ bị sai. Cho phép "Howya" trong cột NGÀY của HÓA ĐƠN sẽ là sai.
  • Mã ít bị lỗi hơn: bạn không phải viết mã để đảm bảo dữ liệu được truy xuất từ ​​cột ngày thực sự là một ngày. Nếu các kiểu cột là động, bạn sẽ phải thực hiện nhiều kiểm tra kiểu khi đọc chúng.
  • Hiệu quả tính toán: Nếu một cột có kiểu INTEGER và bạn SUM () nó, thì RDBMS không phải áp dụng mỹ phẩm điểm nổi.
  • Hiệu quả lưu trữ: cho biết một cột là VARCHAR (10) cho phép RDBMS phân bổ không gian chính xác hơn.
  • Tính toàn vẹn và duy nhất tham chiếu: PK (hoặc FK) của bảng không được phép thả nổi, vì tính bằng nhau của dấu phẩy động là khó khăn, do đó bạn phải khai báo chúng theo kiểu không nổi, như ký tự hoặc số nguyên.
  • Tồn tại các RDBMS với các kiểu cột động (không nghiêm ngặt) (SQLite) . Nó sử dụng khái niệm "ái lực kiểu" trong khi vẫn cho phép bạn chèn hầu như mọi thứ vào bất kỳ cột nào mà không phàn nàn. Có những sự đánh đổi mà sẽ không được thảo luận ở đây. Xem câu hỏi này .

8

Do đó, mã cơ sở mà cơ sở dữ liệu được viết có thể phân bổ và sử dụng các bản ghi kích thước cố định, nếu nó biết rằng một trường cụ thể có thể chứa 0 đến 256 ký tự văn bản thì nó có thể phân bổ một khối 256 byte để lưu trữ.

Điều này làm cho mọi thứ nhanh hơn nhiều, ví dụ: bạn không phải phân bổ dung lượng bổ sung theo kiểu người dùng, vì một trường nhất định luôn bắt đầu x byte vào bản ghi tìm kiếm hoặc chọn trên trường đó để luôn kiểm tra x byte vào mỗi bản ghi, v.v.


Nếu chỉ có tất cả các câu trả lời có thể ngắn gọn và chính xác này ...
Darren Ringer

6

Khi các cột của cơ sở dữ liệu được cung cấp các loại được xác định, các loại thường được xác định để có kích thước nhất định theo bit. Kết quả là:

1) khi công cụ cơ sở dữ liệu đang duyệt qua các hàng trong bảng, nó không phải thực hiện bất kỳ phân tích cú pháp ưa thích nào để xác định nơi mỗi bản ghi kết thúc, chỉ có thể biết rằng mỗi hàng bao gồm, 32 byte, và để có được bản ghi tiếp theo đủ để thêm 32 byte vào vị trí bản ghi hiện tại.

2) khi tìm kiếm một trường trong một hàng, có thể biết một lần bù chính xác cho trường đó mà không cần phân tích cú pháp gì, vì vậy tra cứu cột là một hoạt động số học đơn giản thay vì xử lý dữ liệu có thể tốn kém.


Các trường có độ dài cố định có thể giúp xử lý hiệu quả hơn do độ dài bản ghi và độ lệch trường nhất quán, nhưng các trường có độ dài thay đổi có thể vô hiệu hóa các lợi ích đó vì độ dài bản ghi và độ lệch của các trường có thể khác nhau. Tương tự, nén ở mức bản ghi sẽ dẫn đến các bản ghi có độ dài thay đổi, do đó, vị trí của một bản ghi đã cho không thể được tính toán đơn giản.
Zenilogix

Điều này là đúng và đó là lời khuyên phổ biến trong một thời gian dài để tránh các trường có chiều dài thay đổi vì lý do chính xác đó. Tôi không biết làm thế nào những người chơi lớn làm điều đó nhưng có vẻ như bạn có thể lấy lại một số lợi ích của độ dài cố định bằng cách lưu trữ các trường có chiều rộng thay đổi trong một bảng hoặc khối bộ nhớ không hiển thị và có biểu diễn bảng chính của các trường đó là một 'con trỏ' (chiều rộng cố định) vào nó. Việc xem xét bạn nên thường xuyên thực hiện quét toàn bộ các trường có độ dài thay đổi ở vị trí đầu tiên, lần đánh hiệu suất của cảm ứng có thể đáng để duy trì độ rộng cố định.
UserNotFound

3

Bạn đã hỏi tại sao DBMS có kiểu dữ liệu tĩnh.

  1. Tốc độ tra cứu. Toàn bộ quan điểm của DBMS là lưu trữ nhiều dữ liệu hơn mức bạn có thể tải vào một chương trình. Hãy nghĩ rằng "tất cả các phiếu tín dụng được tạo ra trên thế giới trong mười năm qua". Để tìm kiếm dữ liệu đó một cách hiệu quả, các loại dữ liệu có độ dài cố định rất hữu ích. Điều này đặc biệt đúng đối với dữ liệu có cấu trúc như tem ngày và số tài khoản. Nếu bạn biết những gì bạn đang giải quyết trước thời hạn, việc tải vào các chỉ mục hiệu quả sẽ dễ dàng hơn.

  2. Tính toàn vẹn và các ràng buộc. Việc giữ sạch dữ liệu sẽ dễ dàng hơn nếu nó có các kiểu dữ liệu cố định.

  3. Lịch sử. Các RDBMS đã bắt đầu khi các máy tính chỉ có vài megabyte RAM và dung lượng lưu trữ ở quy mô terabyte rất đắt. Tiết kiệm hàng tá byte trong mỗi hàng của bảng có thể tiết kiệm hàng ngàn đô la và thời gian trong những trường hợp đó.

  4. Lời nguyền của cơ sở khách hàng. Các RDBMS ngày nay rất phức tạp, được tối ưu hóa cao, các gói phần mềm và chúng đã được sử dụng trong nhiều thập kỷ để tích lũy dữ liệu. Họ trưởng thành. Họ làm việc. Một sự cố RDBMS dẫn đến mất dữ liệu quy mô lớn là rất hiếm ngày nay. Chuyển sang một cái gì đó với một hệ thống gõ dữ liệu linh hoạt hơn không đáng giá hoặc rủi ro cho hầu hết các tổ chức.

Tương tự: có thể mù quáng rõ ràng rằng các hệ thống tàu điện ngầm đô thị sẽ hoạt động tốt hơn (yên tĩnh hơn, nhanh hơn, tiết kiệm điện hơn) trên một đường ray hẹp hơn. Nhưng làm thế nào bạn sẽ thay đổi tất cả các đường ray trong hệ thống tàu điện ngầm Thành phố New York để nhận ra những cải tiến đó? Bạn không, vì vậy bạn tối ưu hóa những gì bạn có.


3

Nói chung, bạn càng nói chi tiết về cơ sở dữ liệu về những gì bạn đang lưu trữ, thì càng có thể cố gắng tối ưu hóa các số liệu hiệu suất khác nhau liên quan đến dữ liệu đó, chẳng hạn như phân bổ bao nhiêu dung lượng trên đĩa hoặc phân bổ bộ nhớ khi lấy nó .

Tại sao văn bản trung gian, văn bản dài và văn bản?

Không chắc chắn cơ sở dữ liệu nào bạn sử dụng vì vậy tôi sẽ phải đoán: Tôi đoán rằng hai trong số các kiểu dữ liệu này có giới hạn trên, một trong số chúng không có. Sử dụng kiểu dữ liệu cho văn bản có giới hạn trên cho biết cơ sở dữ liệu cần bao nhiêu dung lượng lưu trữ cho mỗi bản ghi. Cũng có thể một số cơ sở dữ liệu có thể có các cách khác nhau để lưu trữ văn bản lớn (có thể không giới hạn) so với văn bản có độ dài cố định nhỏ (điều này có thể thay đổi theo cơ sở dữ liệu, hãy kiểm tra hướng dẫn của bạn để xem về văn bản của bạn).

Tại sao thập phân, float và int?

Các mức độ chính xác khác nhau đòi hỏi lượng lưu trữ khác nhau, và không phải việc sử dụng nào cũng đòi hỏi mức độ chính xác cao nhất. Ví dụ: xem tại đây: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htmlm#QueryRF50950

Oracle có khá nhiều loại số khác nhau với các yêu cầu lưu trữ khác nhau và khả năng khác nhau về mức độ chính xác và kích thước của số có thể được biểu diễn.


2

Ở một mức độ nào đó, nó mang tính lịch sử.

Ngày xửa ngày xưa, dữ liệu dạng bảng được lưu trữ trong các tệp bao gồm các bản ghi có độ dài cố định lần lượt bao gồm các trường được xác định trước sao cho một trường nhất định luôn cùng loại và ở cùng một vị trí trong mỗi và mọi bản ghi. Điều này làm cho việc xử lý hiệu quả và hạn chế sự phức tạp của mã hóa.

Thêm một số chỉ mục vào một tệp như vậy và bạn có sự khởi đầu của cơ sở dữ liệu quan hệ.

Khi cơ sở dữ liệu quan hệ phát triển, họ bắt đầu giới thiệu nhiều loại dữ liệu và tùy chọn lưu trữ hơn, bao gồm các trường văn bản hoặc trường nhị phân có độ dài thay đổi. Tuy nhiên, điều này đã giới thiệu các bản ghi có độ dài thay đổi và đã phá vỡ khả năng xác định vị trí các bản ghi một cách nhất quán thông qua tính toán hoặc các trường thông qua một phần bù cố định. Không có vấn đề gì, máy móc ngày nay mạnh hơn nhiều so với trước đây.

Đôi khi, rất hữu ích khi đặt kích thước cụ thể cho một trường để giúp thực thi một số logic kinh doanh - giả sử 10 chữ số cho một số điện thoại ở Bắc Mỹ. Phần lớn thời gian chỉ là một chút di sản máy tính.


1

Nếu cơ sở dữ liệu sử dụng các bản ghi có kích thước cố định, mọi bản ghi trong cơ sở dữ liệu sẽ tiếp tục phù hợp, ở cùng một vị trí, ngay cả khi nội dung của nó bị thay đổi. Ngược lại, nếu cơ sở dữ liệu cố lưu trữ các bản ghi bằng cách sử dụng chính xác dung lượng lưu trữ cần thiết cho các trường của họ, việc đổi tên Emma Smith thành Emma Johnson có thể khiến hồ sơ của cô quá lớn để phù hợp với vị trí hiện tại. Nếu bản ghi được chuyển đến nơi nào đó có đủ chỗ, bất kỳ chỉ mục nào theo dõi vị trí cần ghi lại để phản ánh vị trí mới.

Có nhiều cách khác nhau để giảm chi phí liên quan đến các cập nhật đó. Ví dụ: nếu hệ thống duy trì một danh sách các số bản ghi và vị trí dữ liệu, danh sách đó sẽ là thứ duy nhất cần được cập nhật nếu bản ghi di chuyển. Thật không may, các cách tiếp cận như vậy vẫn có chi phí đáng kể (ví dụ: giữ ánh xạ giữa các số bản ghi và vị trí sẽ yêu cầu truy xuất bản ghi sẽ yêu cầu thêm một bước để truy xuất dữ liệu được liên kết với một số bản ghi đã cho). Sử dụng các bản ghi có kích thước cố định có vẻ không hiệu quả, nhưng nó làm cho mọi thứ đơn giản hơn rất nhiều.


1

Đối với nhiều việc bạn làm với tư cách là một nhà phát triển web, không cần phải hiểu những gì đang xảy ra "dưới mui xe". Có những lúc, tuy nhiên, khi nó giúp.

Lợi ích của việc nói với cơ sở dữ liệu là "Sẽ chỉ có 256 byte dữ liệu văn bản thuần túy trong các mục vào cột này." hoặc "Cột này có thể có các mục nhập văn bản lên tới 16.777.215 byte"?

Như bạn nghi ngờ, lý do là để làm với hiệu quả. Sự trừu tượng rò rỉ . Một truy vấn như SELECT author FROM bookscó thể chạy khá nhanh khi kích thước của tất cả các trường trong bảng được biết đến.

Như Joel nói,

Làm thế nào để một cơ sở dữ liệu quan hệ thực hiện SELECT author FROM books? Trong cơ sở dữ liệu quan hệ, mỗi hàng trong một bảng (ví dụ: bảng sách) có độ dài chính xác bằng byte và mỗi trường luôn ở một mức bù cố định từ đầu hàng. Vì vậy, ví dụ: nếu mỗi bản ghi trong bảng sách dài 100 byte và trường tác giả ở offset 23, thì có các tác giả được lưu trữ ở byte 23, 123, 223, 323, v.v. bản ghi tiếp theo trong kết quả của truy vấn này? Về cơ bản, đây là:

pointer += 100;

Một hướng dẫn CPU. Faaaaaaaaaast.

Rất nhiều thời gian, bạn đang làm việc đủ xa khỏi nền tảng nghiệt ngã của nitty mà bạn không cần phải quan tâm đến nó. Là một nhà phát triển web dựa trên PHP, bạn có quan tâm đến việc có bao nhiêu lệnh CPU mà mã của bạn sử dụng không? Hầu hết thời gian, không, không thực sự. Nhưng đôi khi thật hữu ích khi biết, vì hai lý do: nó có thể giải thích các quyết định do thư viện của bạn đưa ra; và đôi khi bạn cần quan tâm đến tốc độ trong mã của riêng bạn.

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.