2012-01-12 52 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