CakePHP:帖子类型的表组织

时间:2013-03-09 23:49:38

标签: php mysql cakephp

我对CakePHP很陌生,我想我已经很快得到了它的要点。我的问题与MySQL有关,但最后我会把Cake带回来。

我正在创建一个论坛/公告板的应用程序。目前我的数据库中有一个帖子条目,其中包含常用的内容:id,title,body等等。

我的问题:我想实现各种不同类型的“帖子”。像照片帖子,文本帖子,员工帖子等(类似于tumblr如何组织其帖子)。我应该为每种类型的帖子制作单独的表格,例如text_posts,photo_posts等吗?或者我可以在常规的Post表中使用像“image_url”那样的字段,如果它在创建时保留为空,那么我将视图解释为文本帖子吗?

如果我要为每种不同类型创建单独的表,我会在公告板控制器中设置所有这些不同的帖子,以便我可以在公告视图中显示它们。但是在视图中,我如何根据它们的创建时间在一个漂亮的Feed中显示它们?我不想让for循环显示所有文本帖子,所有照片帖子等。我希望他们将它们拼接在一起。

3 个答案:

答案 0 :(得分:2)

在我看来,您的数据库结构中存在继承问题。

  

关系数据库不支持继承

我知道如何解决这个问题的三种可能方式是:

1.Single Table Inheritance(所有帖子都有一个表,然后会有很多NULL值。)

2.Class Table Inheritance(尝试实现继承,但将您在PHP中创建的每个对象映射到表中。)

3.Concrete Table Inheritance(每种帖子的单独表格)

哪种解决方案对你更好我无法分辨。它们各有优缺点。

编辑:PHP部分

虽然我对PHP知之甚少,但您可能会这样做:

如果选择选项3将帖子存储在数据库中,您仍然可以选择在PHP中引入继承。循环遍历父类对象(Post)并通过检查它是否是该对象类型的实例来显示特定于子项(Photo,Text等)的属性。

答案 1 :(得分:1)

理论上,您可以为每个表创建一个不同的表,并在其上写一个视图。不幸的是,MySQL不支持您需要插入的触发器。 这是一个使用sqlite3的例子。

create table PhotoTable (
id     integer not null PRIMARY KEY AUTOINCREMENT,
PhotoName varchar(255),
Camera    varchar(255)
);


create table StaffTable (
  id integer not null PRIMARY KEY AUTOINCREMENT,
  StaffName varchar(255)
); 

--- Odd way of seeding AUTOINCREMENT value in SQLite3
insert into StaffTable(StaffName) values('odd');
delete from StaffTable;
update SQLITE_SEQUENCE set seq = 100000 where name ='StaffTable';


create view posts as
select id, 'Photo' as Type, PhotoName, Camera, NULL as StaffName from PhotoTable
union all 
select id, 'Staff' as Type, NULL as PhotoName, NULL as Camera,StaffName from StaffTable;



create trigger postsinsert
instead of insert on posts
for each row
begin
    insert into PhotoTable(PhotoName, Camera) select new.PhotoName, new.Camera where New.Type ='Photo';
    insert into StaffTable(StaffName) select new.StaffName where New.Type = 'Staff';
end;


insert into posts(Type, PhotoName, Camera) values('Photo','photo1','nk');
insert into posts(Type, PhotoName, Camera) values('Photo','photo2','canon');
insert into posts(Type, StaffName) values('Staff', 'spaceghost');

,你得到了

的预期结果
 select * from posts;
1|Photo|photo1|nk|
2|Photo|photo2|canon|
100001|Staff|||spaceghost

答案 2 :(得分:0)

我认为2个表应该比为每种类型创建新表更好。

你可以拥有posts table和post_types表,在posts表中你可以拥有post_type_id外键,这样可以帮助你增加类型,而不必每次都创建一个新表。

然后在posts表中,使列尽可能通用,例如,您可以使用“value”列来保存图像URL或其他任何基于帖子类型的列。

在这个阶段还值得考虑的是,如果你的帖子需要有多种类型,在这种情况下,桥接表会很方便,所以一个表用于帖子另一个用于类型,第三个用于保存帖子和输入id作为外键。