2012-01-12 51 views
1

我不是一個專業的Web開發人員,但是我在高中時涉獵了php。我目前正致力於更新我在大學所屬的一個組織的網站。我真的沒有一個簡潔的方式來問我quesetion,所以我就舉一個例子:在代碼中引用MySQL表鍵的最佳方式

對於我們組織的辦事處,表是這樣的:

officeid_officename 
+------------+------------+ 
| officeid | officename | 
+------------+------------+ 
| 1   | president | 
| ...  | ...  | 
+------------+------------+ 

officeid_memberid 
+------------+----------+ 
| officeid | memberid | 
+------------+----------+ 
| 1   | 234  | 
| ...  | ...  | 
+------------+----------+ 

memberid_memberdata 
+------------+------------+-----+ 
| memberid | membername | ... | 
+------------+------------+-----+ 
| ...  | ...  | ... | 
| 234  | John Smith | ... | 
| ...  | ...  | ... | 
+------------+------------+-----+ 

至於我能告訴,這將是一個適當的設計表格,因爲它允許1)任意改變辦公室名稱(例如,如果「總統」成爲「最高霸主」)2)它允許成員隨意添加和刪除從辦公室3)最終,每個成員的數據可以改變,而不需要該成員與受影響的辦公室的鏈接。

我遇到的問題是,在我寫的代碼中,我的授權取決於成員擁有的辦公室。我可以考慮代表哪些辦事處可以執行哪些操作的三種選擇。

1)使用「總統」等作爲標識檢查(如if($officename === "president") { ... do something ... }

  • 不過,這似乎擊敗表設計的目的,如在辦公室名稱的變化將打破授權。

2)使用officeid作爲標識符檢查(如if($officeid === 1) { ... do something ... }

  • 然而,這似乎缺乏可維護性,開發商不斷地將要引用數據庫,看看有什麼ID指他們在編輯當前代碼或編寫未來代碼時使用哪個辦公室。

3)在配置文件中,使得PRESIDENT_CONSTANT = 1,或類似的東西定義常量和檢查對常量(如if($officeid === PRESIDENT_CONSTANT) { ... do something ... }

  • 然而一)本發行股票與(1)該位置的名稱可能會改變b)這基本上是重新創建officeid_officename表中的配置文件

出了三個選項,我覺得二號是最正確的,但我有一個關於揮之不去的情懷maintai可行性問題。有沒有更好的方法來完成我需要在這裏做的事情?

謝謝。

回答

0

是,#2是正確的。

我不太確定爲什麼你擔心你「不斷需要引用數據庫」。

假設你正在編寫一個經典的PHP web應用程序,每個頁面加載從一開始就執行你的腳本。如果您在開始時檢查辦公室並存儲結果,您可以通過每頁加載的單個查詢獲得結果。無論如何,數據庫都會針對查詢進行高度優化 - 其中一些數據庫不會對您造成傷害。

上述模型的唯一缺點是您有潛在的競爭條件:如果數據庫在期間更改單次執行,則表明您有一種特權升級漏洞。

爲了解決這個問題,一種方法是在開始時通過數據庫進行身份驗證(即檢查辦公室),緩存結果,然後運行代碼並排隊SQL事務中的任何數據庫工作。然後在將頁面發送給用戶之前重新進行身份驗證。如果身份驗證失敗,則向用戶發送錯誤並回滾事務。如果成功(即辦公室匹配緩存的結果),則向用戶發送頁面內容並提交事務。

如果你不是一個專業的網絡開發人員,這可能需要考慮很多,但軟件(即使是大學組織)有一種方法可以在非預期的地方使用,所以最好在開始之前考慮安全後果寫作。

+0

我會編輯代碼來澄清,我不擔心服務器負載,我擔心在代碼中寫入'if($ office = 1)'等事情,並期待未來的網站管理員離開,因爲它看起來很任意對某人進來。 – 2012-01-12 13:26:07

+0

啊,在這種情況下,適當的做法是將其包裝在一個明確命名的函數中。 (這也有助於通過抽象邏輯來實現可維護性。)因此,而不是:if($ office == 1)[[請注意兩個符號!]]嘗試:if(userHasPrivilege(ADMINISTER_FOO))或類似的東西 - 然後執行邏輯檢查:function userHasPrivilege($ requestedPrivilege){}。 – 2012-01-12 18:44:32

+0

我喜歡使用這些功能的想法。謝謝一堆! – 2012-01-18 05:08:08

2

第二個是好的。然後你就可以找到哪些成員的辦公室有這個SQL:

SELECT memberid FROM officeid_memeberid WHERE officeid = 1 AND is_del = 0; 

,你也可以找到其辦公室的成員與此SQL現在加盟:

SELECT officeid FROM officeid_memeber_id WHERE memberid = 234 AND is_del = 0; 

is_del場使用時更新你想從一個辦公室中刪除成員或某個成員:

INSERT INTO officeid_memberid (officeid,memberid,is_del) values (1,234,0);

當刪除:

UPDATE officeid_memberid SET is_del = 1 WHERE memberid = 234 AND officeid = 1; 

所以你可以找到哪個辦公室成員加入,現在不是。

+0

是的。 'officename'就是這個 - 辦公室的名字。你不應該以任何特權爲基礎,而應該在辦公室本身 - 「officeid」。 – Borodin 2012-01-12 01:14:41