需要有关mysql规范化和php类结构的建议

时间:2010-11-19 12:08:24

标签: php mysql database class-design normalization

我正在尝试构建一个记录日志,媒体(照片,视频,音频)上传统计信息的系统。所以我想出了3个表,1个用于音频,1个用于视频,1个用于照片。这是结构

+-----------+---------+------+-----+---------+----------------+
| Field     | Type    | Null | Key | Default | Extra          |
+-----------+---------+------+-----+---------+----------------+
| id        | int(11) | NO   | PRI | NULL    | auto_increment |
| member_id | int(10) | NO   |     | NULL    |                |
| counter   | int(11) | NO   |     | NULL    |                |
| daydate   | text    | NO   |     | NULL    |                |
| epochtime | text    | NO   |     | NULL    |                |
+-----------+---------+------+-----+---------+----------------+

所有三个表都有相同的字段,因为我认为(到目前为止)我需要区分每个和特定表上的媒体,这是多余的吗?

无论如何,因为每个媒体都被视为相同,所以我认为我应该只构建一次类,并根据我当时正在访问的媒体使用这些方法。这是班级:

require_once(INC_PATH.DS.'database.php');

    class Log extends DatabaseObject {

        protected static $db_fields = array('id', 'member_id', 'counter',  'daydate', 'epochtime');

        public $id;
        public $member_id;
        public $counter;
        public $daydate;
        public $epochtime;

        public function find_counter($table_name){
            global $database;
            $time = date('d-m-Y');
            $timestamp = time();

            $sql  = "SELECT * FROM ". $table_name;
            $sql .= " WHERE daydate = '".$this->daydate."'";            
            $sql .= " AND member_id = '".$this->member_id."'";

            return self::find_by_sql($sql);
        }

        public function add_log($table_name){
            global $database;
            $tes = $this->find_counter();

            if(!empty($tes)){
                $sql  = "UPDATE ".$table_name;
                $sql .= " SET counter = counter+1";
                $sql .= " WHERE daydate = '".$this->daydate."'";
                $sql .= " AND member_id = '".$this->member_id."'";

                $database->query($sql);
                return ($database->affected_rows() == 1) ? true : false;
            }else{

                $sql  = "INSERT INTO ".$table_name;
                $sql .= " (id, member_id, user_privelege, counter, daydate, epochtime)";
                $sql .= " VALUES ('', '".$this->member_id."'";
                $sql .= " , '".$this->user_privelege."', '1', '".$this->daydate."', '".$this->epochtime;
                $sql .= "')";

                $database->query($sql);
                return ($database->affected_rows() == 1) ? true : false;
            }
        }

  }

到目前为止,这几乎是有效的,但我仍然怀疑我将表分成3个表的方式,以及我使用$ table_name作为参数的方式。任何更好的方法的建议?我真的想改进我的代码,非常感谢

此致

更新

好吧,根据每个人的回答,我想澄清一些事情:

  1. 我只需要记录上传的媒体
  2. 我已经有另一个单独的表来记录每种媒体的其他信息(长度,文件名,标题等)。
  3. 我只想说我添加一个名为“media_id”的字段并将该表合并为一个,并且由于我添加和更新行的方式基于日期日期,因此如果给定的日期和member_id将会INSERT找不到,否则它会更新,我想我也应该改变我的add_log()方法的工作方式,如:

    public function add_log($table_name, $media_id){
        global $database;
        $tes = $this->find_counter();
    
        if(!empty($tes)){
            $sql  = "UPDATE ".$table_name;
            $sql .= " SET counter = counter+1";
            $sql .= " WHERE daydate = '".$this->daydate."'";
            $sql .= " AND member_id = '".$this->member_id."'";
            $sql .= " AND media_id = '".$media_id."'";
    
            $database->query($sql);
            return ($database->affected_rows() == 1) ? true : false;
        }else{
    
            $sql  = "INSERT INTO ".$table_name;
            $sql .= " (id, member_id, media_id, counter, daydate, epochtime)";
            $sql .= " VALUES ('', '".$this->member_id."'";
            $sql .= " , '".$media_id."', '1', '".$this->daydate."', '".$this->epochtime;
            $sql .= "')";
    
            $database->query($sql);
            return ($database->affected_rows() == 1) ? true : false;
        }
    }
    
    你觉得怎么样?

    再次感谢

2 个答案:

答案 0 :(得分:2)

将所有内容放在一个表格中,并有一个media_type列。

+-----------+---------+------+-----+---------+----------------+
| Field     | Type    | Null | Key | Default | Extra          |
+-----------+---------+------+-----+---------+----------------+
| id        | int(11) | NO   | PRI | NULL    | auto_increment |
| member_id | int(10) | NO   |     | NULL    |                |
| counter   | int(11) | NO   |     | NULL    |                |
| daydate   | text    | NO   |     | NULL    |                |
| epochtime | text    | NO   |     | NULL    |                |
| media_type| int     | NO   |     | NULL    |                |
+-----------+---------+------+-----+---------+----------------+

创建与另一个定义media_type的表的外键关系。

+-----------+---------+------+-----+---------+----------------+
| Field        | Type | Null | Key | Default | Extra          |
+-----------+---------+------+-----+---------+----------------+
| media_type_id| int  | NO   | PRI | NULL    |                |
| description  | text | NO   |     | NULL    |                |
 +-----------+---------+------+-----+---------+----------------+

这将保持media_type_id(例如1)和media_type_description(例如音频)。 e.g。

1, audio
2, video
3, photo

然后,主表将在每行上包含1,2,3的id,以表示它是哪种媒体类型。然后,您可以在应用程序中使用它来通过WHERE子句约束您所引用的媒体。例如SELECT * FROM maintable WHERE media_type_id = 3来获取照片。

答案 1 :(得分:2)

使其成为一个带有额外列“media_type”的表。您的设计需要为每种新媒体类型制作一个额外的表格,并且可能设计不佳。