Php 对于静态查找表,我通常创建静态常量文件(例如#3)。我通常使用以下类: namespace Constants; class UserTypes { const ADMIN = 1; const USER = 2; const GUEST = 3; } $id = Constants\UserTypes::ADMIN;
当我使用更可变的lookup take时,我会将它拉入一个对象,然后缓存24小时。这样一来,它每天只更新一次。这将使您免于进行数据库往返,但允许您轻松地用代码处理事情。是的,您关于避免使用#3而坚持使用#2是正确的。请尽可能地像使用usertype表来包含角色,然后使用id值将它们与用户表关联时那样查看,id值应保留在数据库中。如果使用常量,则数据必须始终依赖于要解释的php代码。此外,您可以通过使用外键(在服务器允许的情况下)强制执行数据完整性,并允许您将报告从php代码移植到其他报告工具。维护也变得更容易。如果您使用了#3,数据库管理员不需要了解php就可以得出数字的含义,如果他们被要求帮助开发报表。这看起来可能不太相关,但就维护而言,在php代码中使用存储过程而不是嵌入式sql在几个方面对维护都很友好,而且对DBA也很有利 我选择选项#2并按预期使用连接。你永远不知道未来会发生什么,今天做好准备总是更好的 至于让数据库尽可能地独立于此类操作,也有可能长期缓存。对于这个路由,PHP中的一个选项是使用一个文件缓存,这个缓存只有在时间需要时才会更新。对于我创建的框架,这里有一个示例;我很想知道人们是怎么想的: 注: (LStore、LFetch、GetFileName)属于静态调用的缓存对象 (Blobify和Unblobify)属于始终处于活动状态的SystemComponent对象 每段缓存数据都有一个密钥。这是你唯一需要记住的事情Php 对于静态查找表,我通常创建静态常量文件(例如#3)。我通常使用以下类: namespace Constants; class UserTypes { const ADMIN = 1; const USER = 2; const GUEST = 3; } $id = Constants\UserTypes::ADMIN;,php,design-patterns,database-design,Php,Design Patterns,Database Design,当我使用更可变的lookup take时,我会将它拉入一个对象,然后缓存24小时。这样一来,它每天只更新一次。这将使您免于进行数据库往返,但允许您轻松地用代码处理事情。是的,您关于避免使用#3而坚持使用#2是正确的。请尽可能地像使用usertype表来包含角色,然后使用id值将它们与用户表关联时那样查看,id值应保留在数据库中。如果使用常量,则数据必须始终依赖于要解释的php代码。此外,您可以通过使用外键(在服务器允许的情况下)强制执行数据完整性,并允许您将报告从php代码移植到其他报告工具。维
public function LStore($key,$data, $blnBlobify=true) {
/* Opening the file in read/write mode */
$h = fopen(self::GetFileName($key, 'longstore'),'a+');
if (!$h) throw new Exception('Could not write to cache');
flock($h,LOCK_EX); // exclusive lock, will get released when the file is closed
fseek($h,0); // go to the start of the file
/* truncate the file */
ftruncate($h,0);
if($blnBlobify==true) { $data = SystemComponent::Blobify(array($data)); }
If (fwrite($h,$data)===false) {
throw new Exception('Could not write to cache');
}
fclose($h);
}
public function LFetch($key) {
$filename = self::GetFileName($key, 'longstore');
if (!file_exists($filename)){ return false;}
$h = fopen($filename,'r');
if (!$h){ return false;}
/* Getting a shared lock */
flock($h,LOCK_SH);
$data = file_get_contents($filename);
fclose($h);
$data = SystemComponent::Unblobify($data);
if (!$data) {
/* If unserializing somehow didn't work out, we'll delete the file */
unlink($filename);
return false;
}
return $data;
}
/* This function is necessary as the framework scales different directories */
private function GetFileName($key, $strCacheDirectory='') {
if(!empty($strCacheDirectory)){
return SystemComponent::GetCacheAdd() . $strCacheDirectory.'/' . md5($key);
} else {
return SystemComponent::GetCacheAdd() . md5($key);
}
}
public function Blobify($Source){
if(is_array($Source)) { $Source = serialize($Source); }
$strSerialized = base64_encode($Source);
return $strSerialized;
}
public function Unblobify($strSerialized){
$Decoded = base64_decode($strSerialized);
if(self::CheckSerialized($Decoded)) { $Decoded = unserialize($Decoded); }
return $Decoded;
}
function CheckSerialized($Source){
$Data = @unserialize($Source);
if ($Source === 'b:0;' || $Data !== false) {
return true;
} else {
return false;
}
}
现在,在访问实际数据时,我只调用一个fetch。为了确保它是最新的,我告诉它去商店。在您的情况下,这将在更新usertype表之后进行。我建议#3避免无用的查询,并防止在意外修改现有DB表行时发生行为更改的风险:
- 在模型类中添加必要的常量:
}class Role // + use namespaces if possible { // A good ORM could be able to generate it (see @wimvds answer) const ADMIN = 1; const USER = 2; const GUEST = 3; //...
- 那么像这样的查询是有意义的:
使用ORM(例如,在下面的示例中),您将完成以下工作:$query = "SELECT info, foo FROM user WHERE role_id = ".Role::ADMIN;
$isAdminResults = UserQuery::create()->filterByRoleId(Role::ADMIN);
name
)不是很直观。哦,我的错。被varchar列上的连接弄糊涂了(我认为效率不高)。顺便问一下,这个sql语句会产生任何结果吗?!关于这种方法还有一件事:最好限制它可以包含的值,例如:ereg(“^[a-z]{1}[a-z0-9_307;]{0254}$”,$hid),即允许使用小写、字母数字和下划线。如果您不是唯一一个可以输入值的人,那么它非常有用……是的,name列应该是唯一的索引,否则效率会非常低。你说得对#2中的查询是错误的:S--刚刚修复了它,谢谢!我知道这对于你的需求来说似乎有些过分,但它可以在整个网站上反复使用。
usertype_id (primary key) | name | description | hid (unique key)
---------------------------+------------+-------------------+---------------
1 | 'admin' | 'Administrator' | 'admin'
2 | 'reguser' | 'Registered user' | 'user'
3 | 'guest' | 'Guest' | 'guest'
select usertype_id from tablename where hid = "admin"
foreach (getdbarr("SELECT * FROM usertype") as $row) {
define($row['name'],$row['id']);
}
$user = DAO_User::get(1); // this pulls a JOIN-less record
$role = $user->getRole(); // lazy-load
public function getRole() {
// This comes from a cache that may be called multiple
// times per request with no penalty (i.e. store in a registry)
$roles = DAO_UserRoles::getAll();
if(isset($roles[$this->role_id]))
return $roles[$this->role_id];
return null; // or: new Model_UserRole();
}
namespace Constants;
class UserTypes {
const ADMIN = 1;
const USER = 2;
const GUEST = 3;
}
$id = Constants\UserTypes::ADMIN;
public function LStore($key,$data, $blnBlobify=true) {
/* Opening the file in read/write mode */
$h = fopen(self::GetFileName($key, 'longstore'),'a+');
if (!$h) throw new Exception('Could not write to cache');
flock($h,LOCK_EX); // exclusive lock, will get released when the file is closed
fseek($h,0); // go to the start of the file
/* truncate the file */
ftruncate($h,0);
if($blnBlobify==true) { $data = SystemComponent::Blobify(array($data)); }
If (fwrite($h,$data)===false) {
throw new Exception('Could not write to cache');
}
fclose($h);
}
public function LFetch($key) {
$filename = self::GetFileName($key, 'longstore');
if (!file_exists($filename)){ return false;}
$h = fopen($filename,'r');
if (!$h){ return false;}
/* Getting a shared lock */
flock($h,LOCK_SH);
$data = file_get_contents($filename);
fclose($h);
$data = SystemComponent::Unblobify($data);
if (!$data) {
/* If unserializing somehow didn't work out, we'll delete the file */
unlink($filename);
return false;
}
return $data;
}
/* This function is necessary as the framework scales different directories */
private function GetFileName($key, $strCacheDirectory='') {
if(!empty($strCacheDirectory)){
return SystemComponent::GetCacheAdd() . $strCacheDirectory.'/' . md5($key);
} else {
return SystemComponent::GetCacheAdd() . md5($key);
}
}
public function Blobify($Source){
if(is_array($Source)) { $Source = serialize($Source); }
$strSerialized = base64_encode($Source);
return $strSerialized;
}
public function Unblobify($strSerialized){
$Decoded = base64_decode($strSerialized);
if(self::CheckSerialized($Decoded)) { $Decoded = unserialize($Decoded); }
return $Decoded;
}
function CheckSerialized($Source){
$Data = @unserialize($Source);
if ($Source === 'b:0;' || $Data !== false) {
return true;
} else {
return false;
}
}
class Role // + use namespaces if possible
{
// A good ORM could be able to generate it (see @wimvds answer)
const ADMIN = 1;
const USER = 2;
const GUEST = 3;
//...
$query = "SELECT info, foo FROM user WHERE role_id = ".Role::ADMIN;
$isAdminResults = UserQuery::create()->filterByRoleId(Role::ADMIN);