2-3 Mở đầu bằng quan hệ và kết thúc bằng quan hệ

Mở đầu bằng quan hệ và kết thúc bằng quan hệ

Nếu chỉ biết rằng quan hệ chính là tập hợp thì những gì chúng ta biết về mô hình quan hệ không quá một góc của một góc của ngọn núi. Tập hợp tên là quan hệ mang những tính chất đặc trưng. Một trong những tính chất đó là tính chất liên quan sâu đến nguyên lý của SQL, "tính bao đóng".

Nhìn tập hợp từ phép toán

Trong chương trước thì chúng ta đã trọng tâm giải quyết một bộ phận trong cơ sở, quan hệ là một loại tập hợp. Nhưng chỉ như vậy thì vẫn chưa đầy đủ được tất cả những đặc tính của khái niệm quan hệ. Quan hệ không chỉ là tập hợp mà nó còn mang những tính chất khác rất thú vị. Một trong số đó chính là tính bao đóng. Cái này nếu nói một cách rộng ra thì đó là tính chất "Đầu vào và đầu ra của phép toán cùng trở thành quan hệ của nhau", hay nói một cách khác thì đó là tính chất "Bảo đảm việc đóng thế giới của quan hệ". Trong chương này chúng ta sẽ đào sâu hơn vào thế giới của cơ sở dữ liệu với điểm đặc tính của quan hệ này.

Trong SQL có rất nhiều phép toán quan hệ. Từ đầu thì đã có những phép toán cơ bản như ánh xạ, giới hạn, tổng, giao,... rồi sau đó thêm những phép toán khác tiện lợi hơn và cho đến bây giờ đã có một cơ số những phép tính đó tăng lên. Vì quan hệ thoả mãn tính bao đóng nên chúng ta có thể lấy đầu ra của phép tính này là đầu vào của phép tính khác. Theo vậy thì chúng ta có thể thực hiện những sự kết hợp phức tạp hơn như thao tác lấy tổng của ánh xạ hay giao của giới hạn. Tính chất này trở thành cơ sở của những kĩ thuật quan trọng như view hay subquery (truy vấn phụ).

Tính bao đóng của quan hệ cũng giống như khái niệm pipe trong UNIX. File của UNIX cũng có tính bao hàm đối với kết quả xuất hay nhập đối với command. Chúng ta có thể kết hợp những command phức hợp như [cat text.txt| sort + 1| more] rồi ghi nó vào trong script. Đây phản ánh tính mềm dẻo cao trong lập trình Shell của UNIX.

Về hình ảnh thì cũng như người ta trao tay nhau những xô những khi cứu hoả. Người chính là những phép tính, quan hệ hay file chính là những cái xô được trao tay qua tay. Tuy nhiên có một điểm khác với hình ảnh trao tay những xô nước trong cứu hoả chính là qua mỗi lần trao qua một phép tính thì nội dung của cái xô thay đổi. Đây là điểu ngạc nhiên của rất nhiều người đầu tiên tiếp xúc với UNIX ngạc nhiên, đó chính là trong UNIX từ device đến console thì cào nào cũng xử dụng mọi thứ như file. Đây chính là kết quả của sự đưa vào tính bao đóng đối với file của UNIX. Có khá nhiều từ để biểu hiện khái niệm thiết kế của UNIX nhưng với điểm này thì chúng ta có thể gọi nó là "Chủ nghĩa cái gì cũng là file".

Và có thể nói cũng giống như hình thành tập hợp đóng về shell command trong UNIX thì chúng ta có hình thành tập hợp đóng đổi với phép tính của quan hệ trong mô hình quan hệ. Điều này được chứng minh như thiết kế đầu vào và ra của câu lệnh SELECT từ đầu đã được định sẵn là bảng. Câu lệnh SELECT là hàm số lấy argument là bảng (quan hệ) và cũng cho đầu ra là bảng (quan hệ). Có những lúc câu lệnh SELECT không chọn một dòng nào trong bảng nhưng trong trường hợp đó không phải nó không trả lại kết quả gì mà trên thực tế sẽ cẩn thận trả lại kết quả "Tập hợp trống (empty set)". Vì không nhìn thấy tận mắt nên không có cảm giác thực nhưng mà đặc tính này của cơ sở dữ liệu quan hệ nếu đặt tên tựa theo UNIX thì có thể nói đó là "Chủ nghĩa cái gì cũng là quan hệ".

Tính bao đóng nhìn thấy ở hai ví dụ này chính là khái niệm bắt đầu từ toán học. Toán học cũng lấy cơ bản là tuỳ theo sự đóng phép toán như thế nào mà phân loại tập hợp ra nhiều phạm trù khác nhau. Nếu suy nghĩ từ quan điểm này thì chúng ta có thể gọi tập hợp như là cấu tạo đại số. Ví dụ nếu phân loại theo cơ sở đối với 4 kiểu phép toán thì người ta đóng như thế nào thì sẽ thành như dưới đây.

  • Group: đóng về phép cộng, phép trừ (hoặc phép nhân, phép chia)
  • Ring: đóng về phép cộng, phép trừ, phép nhân
  • Field: đóng về phép cộng, phép trừ, phép nhân, phép chia. Nói một cách khác chính là 4 phép toán có thể tự do.

Nếu đưa ra một ví dụ cụ thể thì ví dụ đơn giản nhất về group chính là tập hợp số nguyên. Vì kể cả chúng ta trừ hay cộng những số nguyên với nhau thì kết quả chắc chắn vẫn là số nguyên. Tập hợp số nguyên cũng có thể là Ring nhưng rất tiếc không phải là Field. Lý do sẽ rõ ràng nếu chúng ta nhìn từ phép tính 1/2 là có thể hiểu. Kết quả sẽ là số thập phân, và ở đây tính bao đóng bị phá vỡ. Nếu mở rộng phạm vi ra một chút thành số hữu tỉ hay số thực thì sẽ thành một field rất lớn. Vì nếu lấy số thực để thực hiện thì ta có thực hiện phép tính nào trong 4 phép tính thì kết quả vẫn là số thực.

Untitled.png

Thực hiện và nguyên lý

Vậy thì từ đây "quan hệ" trong kiểu mẫu quan hệ chính là phần nào trong cấu tạo đại số trên?

Nếu suy nghĩ về những phép toán của SQL có thì chúng ta có thể nghĩ đến phép cộng (UNION) hay phép trừ (EXCEPT). Vì vậy nên những điều kiện cho đến group là đã qua. Để thực hiện phép nhân thì chúng ta có thể thực hiện qua CROSS JOIN nên cũng coi như đã clear đến ring. Vậy, phép chia thì sao? Câu lệnh cho phép chia không có... Vậy chúng ta chỉ được dừng ở ring thôi sao?

Đúng, trong SQL thông thường đúng là không có phép chia nhưng chúng ta có thể định nghĩa chính phép tính này như đã viết trong phần "Sức mạnh của câu lệnh HAVING". Vì vậy những điều kiện trong Field cũng clear. Nếu nhìn từ quan điểm những xử lý đối với phép tính thì có thể nghĩ quan hệ là tập hợp có khả năng thực hiện tự do 4 phép tính. Date và Celko coi trọng phép chia không chỉ vì lý do tính thực dụng cao mà còn có lý do họ biết được việc quan hệ có được coi như một Field không phụ thuộc vào việc phép chia có được định nghĩa một cách cẩn thận hay không.

Cũng như những gì được viết ở trên thì mô hình quan hệ là lý luận mang những cơ sở mật thiết đối với toán học. Chính vì vật có thể ứng dụng hoàn toàn những thành quả của lĩnh vực có nhiều thực tích xếp chồng lên nhau như luận tập hợp hay luận về group. Như vậy có thể nói rằng Codd cũng đã biết được tính quan trọng của việc cấu trúc một thể chặt chẽ như thế này. (Và tất nhiên không sai gì khi nói những nhà phát triển nên UNIX cũng vậy). Trên thực tế nếu nếu kết quả của kết hợp hay UNION không thành quan hệ (hay chính là bảng) thì SQL sẽ trở thành một ngôn ngữ không tốt mà người dùng không thể làm điều gì mình muốn. Về một SQL không thể sử dụng subquery thì đối với tình trạng hiện tại thì quả thực là một điều không thể nghĩ tới.

Nếu tóm tắt những điều đã nêu lên ở trên thì đó chính là cũng như file của UNIX có tính bao đóng đối với Shell Command rồi có thể thực hiện nhữn tính năng cấp cao thì SQL bằng việc có tính bao đóng đối với quan hệ, hay chính là đại số quan hệ thì đã có được khả năng biểu hiện cao đối với những phép tính.

Date có một triết lý là "Việc tuân theo sự nghiêm chặt mang tính lý luận chính là việc không thể bớt đi tính thực dụng của lý luận. Nói đúng hơn thì sự nghiêm chặt mang tính lý luận đó chính là tính thực dụng". Thỉnh thoảng thì có thể chúng ta nghe thấy những câu như lý luận không có ích gì trên thực tế nhưng có thể nói đó chính là một sự hiểu lầm rất lớn.

Theory is practical

2-4 Address, đúng là một con quái vật khổng lồ

Tại sao trong cơ sở dữ liệu quan hệ lại không có address? Động cơ của Codd suy nghĩ về mô hình quan hệ đó chính là việc giải thoát sự biểu hiện của dữ liệu từ kết nối ở trình độ vật lý. Lịch sử của cơ sở dữ liệu quan hệ được ghi lại là sự đấu tranh để giải thoát lập trình từ con quái vật tên address.

E.F.Codd đã nói "Động cơ lớn nhất của nghiên cứu sinh ra mô hình quan hệ này chính là sự muốn phân biệt rõ ràng sự quản lý cơ sở dữ liệu về mặt vật lý và về mặt lý luận. Điều này cần bắt đầu từ việc chúng ta cùng gọi đó là mục tiêu về sự độc lập của dữ liệu (data independence objective)".

Hay C.J.Codd có nói "Khi nói rằng cơ sở dữ liệu mô hình quan hệ không có address thì không có nghĩa nói rằng không thể không có hoàn toàn address mang tính vật lý. Ngược lại thì đối với level này thì chắc chắn address có tồn tại và thực tế chính là vậy. Tuy nhiên cũng như đã thuyết minh ở trên thì tất cả những chi tiết về kí ức về tính vật lý như thế này thì trong cơ sở dữ liệu mô hình quan hệ sẽ giấu đối với người dùng."

Mở đầu

Trong cơ sở dữ liệu quan hệ thì đối với lập trình thông thường thì không tồn tại khái niệm mang tính vật lý là address. Một cách chính xác hơn đó chính là có tồn tại nhưng người dùng không thể nhìn thấy được, nó được giấu đi một cách cố tình. Nói như vậy thì chắc hẳn có ý kiến cho rằng không phải chúng ta có một loại address mà user có thể sử dụng như rowid của Oracle hay oid của PostgreSQL hay sao. Đúng như những gì mọi người nghĩ, những cái đó là sự mở rộng độc lập phản thông thường, đối với SQL thông thường cố gắng xoá đi address. Đây là vì để cố gắng không để user nhận thức về khái niệm level vật lý, nâng cao tính trừu tượng cho biểu hiện của dữ liệu.

Tuy nhiên, những điều này chắc hẳn sẽ gây ra một cảm giác khác lạ cho những lập trình viên đã quen với những thao tác address như trong ngôn ngữ C. Chắc hẳn cũng thỉnh thoảng mọi người có thể nghe thấy những ý kiến phản ánh cho rằng "SQl không thể thao tác đối với address, đây là khuyết điểm mà nó đang mang phải".

Tại chương này chúng ta sẽ chuẩn bị, sắp xếp lại những ý tưởng thiết kế cơ bản của SQL từ quan điểm "Giải phóng từ address" để giải toả một cách rõ ràng những mập mờ về SQL của những lập trình viên của ngôn ngữ lập trình thủ tục.

Mô hình quan hệ được sinh ra để trở thành tự do từ những address

Trước khi bắt đầu câu chuyện thì tôi muốn xác nhận trước một điều dĩ nhiên. Hãy quan sát như một lập trình viên không có quan điểm ban đầu. Đối với những nghiệp vụ thực tế trong xã hội, nói một cách chính xác ra thì thứ mà chúng ta mong muốn chính là dữ liệu chứ không phải địa chỉ của dữ liệu. Việc nhận lại được địa chỉ của dữ liệu chỉ tăng thêm những thủ tục cần phải xử lý, đây chắc hẳn không phải là điều chúng ta mong muốn. Việc nhấn mạnh đi nhấn mạnh lại điểm này không phải là một điều thừa. Tại sao lại vậy thì đó chính là ngược với những mong muốn của chúng ta thì trong máy tính luôn tràn đầy những địa chỉ. Không chỉ vậy, trong trường hợp sử dụng ngôn ngữ C hay assembler thì lập trình viên cần thiết phải ý thức sử dụng địa chỉ.

Tuy nhiên, trong cơ sở dữ liệu thì từ năm 1969 coi như đã gần thành công hoàn toàn việc giải phóng address. Khi nói về nguyên lý của mô hình quan hệ thì từ "Mục tiêu độc lập của dữ liệu" có ý nghĩa chính là giải phóng cơ sở dữ liệu từ những địa chỉ. (Nói ngược lại thì mô hình cơ sở dữ liệu trước mô hình cơ sở dữ liệu quan hệ là mô hình tầng và mô hình network ngập tràn trong những địa chỉ). Nếu nghĩ rằng thế giới lập trình vẫn còn đang tiến hành những thao tác về address thì đây chính là những bước thử nghiệm đầu tiên vượt qua nó. Chính vì thế nên những kĩ sư DB hiện tại không cần phải để ý đến nơi có dữ liệu mà chỉ cần để ý đến nội dung dữ liệu là được.

Codd cũng đã nói rất rõ về điều này.

Trong sự quyết định khu đất của thiết bị tính toán cùng với khái niệm về vị trí cho đến nay đã thực hiện những nhiệm vụ rất quan trọng. Xuất phát từ sự quyết định khu đất đối với bảng plug rồi đến những khu đất kí hiệu mang tính chất toán thuật, khu đất tuyệt đối, khu đất tương đối (Như những khi đất yếu tố như X(I+1, J-1) của dãy A+3, Fortran, Algol, PL/I của những khu đất kí hiệu trong ngôn ngữ assembly). Mô hình quan hệ hoàn toàn loại bỏ sự quyết định vị trí dựa theo khu đất và hoàn toàn sử dụng sự quyết định khu đất dựa theo nội dung. Tại cơ sở dữ liệu quan hệ, có thể gọi dữ liệu chỉ bằng tên quan hệ, giá trị primary key hay tên của thuộc tính. Khi cách gọi này có thể sử dụng được thì người dùng có thể để những điều tiếp theo đây cho hệ thống tự xử lý. (1) Chi tiết nơi đặt thông tin mới trong cơ sở dữ liệu. (2) Khi điều tra thông tin, tự quyết định con đường thích hợp để gọi thông tin ra. Tất nhiên lợi điểm này không chỉ đối với người mới sử dụng mà ngay cả đối với những lập trình viên cũng trở nên có ích.

Ở đây chúng ta hiểu khu đất chính là địa chỉ, là địa chỉ không chỉ được sử dụng như để chỉ điểm vị trí mà còn bao gồm tất că những chữ có trong dãy đó. Codd là người không thích sự biểu hiện tất cả dữ liệu theo vị trí như thế này.(Vậy nên trong mô hình quan hệ thông thường không có sự xuất hiện của dãy).

Người đã đi cùng Codd trong thời gian dài là Date đã gửi cho Codd những lời bình sau đánh giá về những nỗ lực khổ tâm của Codd.

"Tiếp theo, quan hệ của cơ sở dữ liệu dù là mô hình như thế nào nhưng cũng không thể có thuộc tính kiểu chỉ điểm vị trí (pointer) được. Cũng như mọi người đã biết, cơ sở dữ liệu xuất hiện trước cơ sở dữ liệu quan hệ đều toàn pointer, để truy cập vào cơ sở dữ liệu thì hầu hết chúng ta bắt buộc phải theo những pointer. Với tình trạng đó thì sự lập trình ứng dụng cũng gặp nhiều lỗi, rồi từ người sử dụng cuối cùng không thể trực tiếp truy cập được. Codd với cơ sở dữ liệu quan hệ với mục tiêu giải quyết những vấn đề đó, và tất nhiên đã thành công."

Phương pháp quản lý dữ liệu chuyển từ vị trí sang nội dung. Cùng với việc chuyển như vậy thì người ta đã chuyển từ trình độ vật lý sang trình độ lý luận (trừu tượng hoá), từ kí hiệu sang tên (ý nghĩa hoá). Chúng ta có thể dễ dàng nhìn thấy việc chuyển đổi này đã mang đến một ân huệ rất lớn cho người sử dụng cuối cùng hay chính cho những lập trình viên. Ai cũng vậy, chúng ta đều dễ hiểu khi chỉ định một nhân vật đặc định nào đó thì so với việc sử dụng một địa chỉ khô khan vô nghĩa như [x002ab45] thì sử dụng cái tên [Yamada Tarou] chắc chắn sẽ tiện hơn nhiều. Chính vì vậy có thể nói việc giải thoát address như thế này sẽ giải thoát chúng ta ra khỏi một hệ thống vô ý nghĩa mà không khác gì đã tạo nên một hệ thống có ý nghĩa mà con người có thể nhận thức dễ dàng.

Câu nói của Codd "Mô hình quan hệ hoàn toàn loại bỏ sự quyết định vị trí dựa theo khu đất và hoàn toàn sử dụng sự quyết định khu đất dựa theo nội dung." chính là một câu trả lời từ quan điểm của mô hình dữ liệu đối với vấn đề lớn mà những kĩ sư phải đối mặt từ khi máy tính mô hình Neumann ra đời với câu hỏi có khi nào có thể chạy thoát ra khỏi sự ràng buộc với address hay không. Và tiếp theo đó, sự thành công của cơ sở dữ liệu quan hệ chính là điều chứng minh cho sự quan sát tài tình của Codd. Hay cũng chính E.S.Raymond cũng nói rồi hay sao,

Sự tràn lan của address trong lập trình

Mô hình quan hệ là không sai, chính là một mô hình dữ liệu ưu tú nhưng không có nghĩa đã hoàn toàn giải phóng cơ sở dữ liệu từ address. Nếu nhìn từ trình độ vật lý thì dữ liệu vẫn không thay đổi mà vẫn chịu sự quản lý của address. Tuy nhiên, theo như hiện thực này mà chúng ta nói mục tiêu độc lập của dữ liệu bị bỏ dở giữa chừng thì cũng hơi quá. (Trong tình hình hiện tại) phương án lựa chọn duy nhất của chúng ta có thể sử dụng đó chính là máy tính kiểu Neumann, trên cả sự quản lý dữ liệu bằng address thì những chương trình chạy trên nền đó cũng phải chịu giới hạn tương tự. Vì vậy, chẳng phải chúng ta nên nghĩ Codd từ trong giới hạn đó muốn tự mình đề ra một mô hình quan hệ có thể bẻ đi cái gì đó sao.

Kể cả chúng ta mở rộng tầm nhìn ngoài SQL ra những ngôn ngữ lập trình thông thường, quả nhiên, từ trong lịch sử đã có những ý kiến lớn nhỏ cho rằng có nên giấu lập trình viên address không. Những ngôn ngữ kế sau ngôn ngữ C hay ngôn ngữ assembly là Pascal, Java hay Perl thì đều cố gắng để giấu user địa chỉ. SQL và cơ sở dữ liệu quan hệ chỉ có chung mục tiêu với những ngôn ngữ hiện thời thôi. Tuy nhiên cũng có nhiều ý kiến chỉ trích chính máy tính của Neumann phải chịu giới hạn về phương thức quản lý dữ liệu nên đã mang đến cho thế giới lập trình một sự trôi nổi lớn của address.

Ngôn ngữ lập trình bị bao bởi address có kết quả như Bacchus đã nói "Trong vòng 20 năm nay, ngôn ngữ lập trình đã tiến triển theo hướng trương phì như thế này", hơn cả những gì ông ta nói thì đối với hiện tai, ngay cả hơn 20 năm đã trôi qua thì tình trạng này vẫn chưa được cải thiện. Mà ngược lại có khi ngày càng trở nên tồi tệ hơn. Trong vòng 20 năm nay trở về trước, có rất nhiều ngôn ngữ lập trình được sinh ra nhưng vì một con quái vật tên là address mà mọi thứ đều không thể trở nên tự do.

Tất nhiên cũng có một bước tiến đó chính là giấu được address với người sử dụng nhưng nếu nhìn từ trong thì đó là một trận lũ về address. Hướng đối tượng cũng không có được những phương thức hữu hiệu đối với sự chìm ngập của address này. Cũng không thay đổi việc dữ liệu bị quản lý bới OID hay object, code cũng trở nên phức tạp và nếu object cứ ngày càng được tạo ra thì tình trạng một ngày nào đó biến số trong ngôn ngữ lập trình thủ tục sẽ chất chồng như núi.

Đúng, biến số chính là một biến thể của address đối với ngôn ngữ lập trình. Tất cả những biến số đều bị quản lý bởi những address không mang ý nghĩa của chính nó. Và để sử dụng dữ liệu đối với ngôn ngữ lập trình thủ tục thì chỉ có một cách là thay vào biến số. Cho đến khi chúng ta vẫn phải sử dụng biến số thì chúng ta vẫn không thoát khỏi lời nguyền của address. Và nói SQL có thể nói là một ngôn ngữ được tự do từ address có một lý do đó chính là vì nó không sử dụng biến số.

Cũng giống như SQL cũng có một ngôn ngữ khác không sử dụng biến số là Lisp. Với tư cách là một ngôn ngữ cấp cao thì nó có lịch sử cổ chỉ sau Fortran, và cũng có thể gọi là lão làng trong thế giới ngôn ngữ. Và một cách kì diệu thì Lisp (hay ngôn ngữ dạng hàm số) được tín nhiệm với hi vọng giải thoát ra khỏi máy tính mô hình Neumann.

Đúng là Lisp và Haskell là ngôn ngữ có khả năng đủ để gánh vác giấc mơ đó. Trên thực tế thì SQL và ngôn ngữ dạng hàm số có rất nhiều điểm chung mà với tư cách là một ngôn ngữ lập trình thì chúng đều hướng đến những mục đích chung. Và nói như thế này chắc hẳn những người đã khuất như Codd và Bacchus cũng không phản đối gì.

Những ngôn ngữ như SQL hay ngôn ngữ dạng hàm số như Lisp đúng là có một chỗ đứng trong ngôn ngữ lập trình hiện tại nhưng cũng chưa bao giờ trở thành trào lưu chính dù chỉ một lần. Tuy nhiên, những năm gần đây SQL thông thường được tiến hành thêm những tính năng phong phú và những điểm mạnh của SQL hay ngôn ngữ dạng hàm số đang được đánh giá lại. Cuộc chiến đấu giải phóng từ address sẽ trở nên như thế nào thì bây giờ vẫn chưa thể dự đoán nhưng chúng ta có thể kì vọng vào một ngày nào đó trong tương lai gần có thể viết được về điều đó.