Mysql

在 SQL 中將內容與表示分離的最佳實踐

  • July 17, 2020

程式的一個常見且有用的範例是分離內容和表示。一個系統負責建構結果,另一個系統負責輸出結果。

您可以通過 HTML 與 CSS 看到這一點。理想情況下,HTML 應該是乾淨的並且沒有任何應該由 CSS 處理的內部樣式(顏色、位置等)。

我現在想知道這如何應用於 SQL 結果。我經常發現自己在查詢中格式化結果:

SELECT 
   CONCAT(first_name, ' ', last_name) AS name,
   DATE_FORMAT(last_edit, '%d/%m/%Y') AS last_edit,
   CONCAT(
       record_type, 
       IF (private = 1, ' (Private)', ' (Public)')
   ) AS record_type
FROM people
ORDER BY updated DESC, LastEdit DESC

這裡涵蓋了三種不同的場景:

  1. 第一列是一個簡單的串聯。
  2. 第二個將輸出轉換為不同的格式。
  3. 第三個實際上將內容添加到結果中。

我知道有許多有用的函式可用於轉換查詢中的數據。但是從團隊開發的角度來看,我應該在表示層而不是邏輯層(即在我的 PHP 程式碼而不是 SQL 查詢中)格式化這些結果嗎?

如果是這樣,那我應該走多遠?第 1 列和第 2 列可以接受,但第 3 列不行嗎?

在這方面是否有被廣泛接受的最佳實踐?

這取決於。沒有一刀切的答案。是的,數據庫是數據的持久儲存——在設計模式時關注這一點。

同時,讓我指出

DATE_FORMAT(last_edit, '%d/%m/%Y') AS last_edit,

暗示需要強烈說明的事情:以通用格式儲存數據:

  • 以適合數據庫的格式將日期和時間儲存在數據庫中。這可能需要在輸入和輸出期間進行轉換。它有助於過濾和排序(如在您的範例中,儘管有拼寫錯誤)。
  • 將文本儲存為 UTF-8,而不是 html-entites、latin1 等。這意味著在數據退出後添加實體(或其他)。 SELECTing
  • 貨幣價值儲存為DECIMAL; 科學如FLOAT/DOUBLE。等等
  • JSON 可以方便地儲存不需要太多排序/搜尋的隨機屬性(想想 EAV)。

但是,讓我們研究一個常見的例子:一個“地址”是否應該被分成address1, address2, city, province, country, postal_code。與可直接列印的address.

決定的一條規則是您是否需要對單個數據進行搜尋/排序。請記住,為此目的拆分欄位非常困難且效率低下。

在另一個極端,你甚至會考慮將圖像分割成像素嗎?(我希望不是。)

現在,回到你的問題。您的範例似乎在幕後具有合理的數據類型。但是你的問題是,當它出現時,由誰來進行格式化。您已經給出了簡單的範例,其中使用 SQL 進行格式化非常簡單。我可能會像您為“簡單”系統所做的那樣編寫它。

如果有任何改變格式的機會(例如,翻轉並添加逗號:“last_name,first_name”),您可能應該將其留給以後的程式碼。

對於更複雜的事情,最好推遲格式化。

SQL中有些東西比較亂,所以還是留待後面的程式碼吧:

  • 樞軸 - 您將二維數據儲存在 1D 中。(關注標籤$$ pivot-table $$)
  • 想要建構表格數據但不複製值(垂直),直到它發生變化。這在 SQL 中太神秘了;最好是格式化程式碼。

至於IF (private = 1, ' (Private)', ' (Public)'), 考慮從 numeric 切換到ENUM('public', 'private').

這取決於你想做什麼:

你可以在javascript/python/php中格式化你的數據,但是由於你不想改變它或使用它,你可以在mysql中格式化,因為你可以直接顯示它,但是你可以使用結果集來計算和格式化你喜歡的一切。

如果你需要它來計算一些東西,你不能格式化它,因為你需要用你正在使用的語言取消格式化它,才能使用它。對於不同的人以不同的方式顯示相同的數據也是如此。所以你不需要更改查詢。

例如,當您的伺服器硬體不是最強時,您可以發送數據,並讓 javascript 完成剩下的工作,因為它執行在使用者電腦上。

結論,你一直在努力改變格式,不管你在哪裡做,sompmy選擇你最熟悉的語言並在那裡程式。

使用 5g 和千兆乙太網,四核和更多 cpu,如果您載入大量數據並讓它在使用者設備上計算通常並不重要,但是當您想要節省頻寬時,您只需計算伺服器上的所有內容並且只讓使用者設備或網路完成最低限度的工作。

引用自:https://dba.stackexchange.com/questions/271159