数据库设计:将sql数据库密钥与php常量匹配?

Vin*_*ent 9 php database-design design-patterns

这是一个简单的设计问题,我多次想知道,从来没有找到一个令人满意的解决方案.我的例子是php-sql,但这当然也适用于其他语言.

我有一个只包含很少条目的小型数据库表,几乎不需要更新.例如这张usertype桌子:

usertype_id (primary key)  | name       | description
---------------------------+------------+-------------------
1                          | 'admin'    | 'Administrator'
2                          | 'reguser'  | 'Registered user'
3                          | 'guest'    | 'Guest'
Run Code Online (Sandbox Code Playgroud)

现在在PHP代码中,我经常需要检查或比较我正在处理的用户类型.由于用户类型存储在数据库中,我可以:

1)在类实例化中从usertype表中选择*,并将其存储在数组中.
然后所有id都可用于代码,我可以做一个简单的选择来获取我需要的行.每次实例化类时,此解决方案都需要一个数组和一个db查询.

$query = "SELECT info, foo FROM user WHERE usertype_id = ".$usertypes['admin'];
Run Code Online (Sandbox Code Playgroud)

2)使用name列选择正确的usertype_id,这样我们就可以有效地与其他表连接.这或多或少等同于1)但不需要在php对象中缓存整个usertype表:

$query = "SELECT info, foo FROM user JOIN usertype USING (usertype_id) WHERE usertype.name = 'admin' ";
Run Code Online (Sandbox Code Playgroud)

3)定义与usertype表中的键匹配的常量:

// As defines
define("USERTYPE_ADMIN",1);
define("USERTYPE_REGUSER",2);

//Or as class constants
const USERTYPE_ADMIN = 1;
const USERTYPE_REGUSER = 2;
Run Code Online (Sandbox Code Playgroud)

然后做一个简单的选择.

$query = "SELECT info, foo FROM user WHERE usertype_id = " . USERTYPE_ADMIN;
Run Code Online (Sandbox Code Playgroud)

这可能是资源效率最高的解决方案,但维护起来不好,因为如果需要修改usertype表中的内容,则必须更新表和代码.

4)废弃usertype表格,只保留php代码中的类型.我真的不喜欢这个,因为它允许任何值进入数据库并被分配给用户类型.但也许,考虑到所有事情,它并没有那么糟糕,我只是简单地复杂化了一些事情.

无论如何,总而言之,我最喜欢的解决方案是#2,因为它是连贯的并且有索引usertype.name,它不会那么糟糕.但我经常最终使用的是#3,以提高效率.

你会怎么做?更好的解决方案?

(编辑:#2中的固定查询)

irc*_*ell 0

为什么不对数据库表进行非规范化,而不是使用usertype_id,而是usertype使用字符串类型 ( admin)。然后在 PHP 中你就可以这样做define('USERTYPE_ADMIN', 'admin');。如果您想添加用户类型,它可以使您不必修改两个位置......

如果您真的担心任何值进入,您始终可以将该列设置为ENUM数据类型,这样它就可以自我管理......