我的webapp的主持人可以修改数据库中的某些数据。所有用户都可以看到这些修改。但出于某些原因,我不希望它们立即应用,而是仅在特定操作后 ,例如,当我明确接受时。时间表是:
PreviousValue
。NewValue
。所有用户继续看到值PreviousValue
。NewValue
。问题是版主可以修改大量表格中的字段。处理这个临时值的最佳方法是什么?我可以想象这些解决方案,但没有一个听起来不错:
MyTable
和MyTable_ToApply
)。ToApplyTable
):要修改的表,要修改的字段,要修改的条目的ID以及要应用的新值。你有更好的想法吗?
答案 0 :(得分:4)
一旦问题相当广泛(并且可以有很多好的答案) - 这不是答案,而是另一种可能的解决方案:
您可以拥有以下表格:
id - just autogenerated number
datetime - date of change
changed_by - string with name of actor or id of some user
oldvalue - just old value
newvalue - just new value
update_insert_sql - here you put actual SQL which should be executed (you already have this sql in your current code)
state - 0 - it is not applied to db, 1 - already executed, 2 - you're rejected this change
datetime_of_apply - just date of action
datetime_of_reject - just date of action
注意:您可以存储SQL以获取当前值,而不是存储旧值,当不同版主对同一行/列进行多次更改时,这将对您有所帮助
因此,在您的界面中,您将能够看到所有表的所有建议更改,仅查看实际值和建议的新值,并在需要时更新数据库
可能的补充:要填充此表,您可以使用触发器,而不是更改当前代码
答案 1 :(得分:3)
这就是wordpress处理这些东西的方式。您可以在同一个表中,一个已发布的帖子,然后,作为新行,由不同的作者创建的未发布的修订集合,在不同的时刻创建,当然也与主帖相关联。
<强>更新强>
例如,如果您使用doctrine,您只需要相同的存储库和一个需要考虑的字段,例如:$rep->findByPublished(1)
所有其余代码保持不变,因此您的控制器不了解业务 - 等级逻辑是否适度,并且不需要处理它。然后在管理员控制器中编写逻辑以将修订设置为主要帖子,并在接受修订时取消发布旧版本。简单,干净,可扩展,可维护和有效的模型。
CREATE TABLE `wp_posts` (
`ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`post_author` bigint(20) unsigned NOT NULL DEFAULT '0',
`post_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', #date of creation of this post o revision
`post_status` varchar(20) NOT NULL DEFAULT 'publish', #publish, unpublish,
`post_name` varchar(200) NOT NULL DEFAULT '', #internal name if you want to better identify revisions
`post_modified` datetime NOT NULL DEFAULT '0000-00-00 00:00:00', #date of modification of this current post or revision
`post_parent` bigint(20) unsigned NOT NULL DEFAULT '0', #if this is a revision, here you have the id of the main post this could replace if it it approved
`post_type` varchar(20) NOT NULL DEFAULT 'post', //basicaly in your case, post or revision, but you can remove this one, since you can check if post_parent is 0 (or NULL if you want)
##Other columns with all the post information
PRIMARY KEY (`ID`),
)
我不喜欢wordpress是如何制作的,但我不得不说这是一个很好的方法。而且,四个肯定:
答案 2 :(得分:3)
更新发生时,创建一个新行并拥有一个主持人需要查看的标志。主持人接受时,将接受的记录标记为活动,将前一记录标记为非活动。在最高级别执行此操作,以便在其他表连接时,它们将继承活动/非活动状态和is_moderated标志。
id | text | is_active | is_moderated | is_accepted
-------------------------------------------------------
1 | hello | 1 | 1 | 1 <-- This is the active row
添加新记录改变你好再见
id | text | is_active | is_moderated | is_accepted
-------------------------------------------------------
1 | hello | 1 | 1 | 1 <-- This is still the active row
2 | goodbye | 0 | 0 | 0 <-- Moderator needs to accept or deny this
接受的结果:
id | text | is_active | is_moderated | is_accepted
-------------------------------------------------------
1 | hello | 0 | 1 | 1 <-- This is NOT the active row
2 | goodbye | 1 | 1 | 1 <-- Accepted, new active row
拒绝国家:
id | text | is_active | is_moderated | is_accepted
-------------------------------------------------------
1 | hello | 1 | 1 | 1 <-- This is still the active row
2 | goodbye | 0 | 1 | 0 <-- Moderator denied
您选择的查询将变为:
获取活动行:
SELECT * FROM TABLENAME WHERE is_active = 1
要获得需要审核的行
SELECT * FROM TABLENAME WHERE is_moderated = 0
答案 3 :(得分:3)
实际上,答案并不那么困难。这是我的想法: -
第1步:
只需在表Posts
(或包含用户的完整帖子的表)中添加一列名为Moderated Post
的列。任何主持人的任何审核或编辑都会进入本专栏。
第2步:
将另一列添加到名为Posts
的表isModerated
中。它包含值1
或0
,就像布尔值true
或false
一样。
第3步:现在,你差不多完成了。你有一张这样的桌子: -
TABLE `POSTS`
| Post id | Initial Post | Moderated Post | isModerated |
_________________________________________________________
| The first | | |
| 1 | post goes | | 0 |
| | here | | |
_________________________________________________________
| | The second | The moderated | |
| 2 | post goes | post goes here | 0 |
| | here |(Post invisible)| |
_________________________________________________________
| | The third | The moderated | |
| 3 | post goes | post goes here | 1 |
| | here | (Post visible) | |
_________________________________________________________
现在在你的PHP代码中,在从表中检索所有值后,你会像这样显示你的帖子(只是一个粗略的草图): -
<?php
if($isModerated == 1) {
echo $moderated_post;
}else {
echo $initial_post;
}
?>
正如您所说,审核会更改多个表中的值,为此您必须添加列(Moderated_Value1
)xn 其中n表示其值可以为的列数改变。示例: -
| Value 1 | Value 2 | Moderated_Value1 | Moderated_Value2 |
| 0 | 1 | 1000 | 2000 |
现在,您的代码变为: -
<?php
if($isModerated == 1) {
echo $moderated_post;
echo $moderated_value1;
echo $moderated_value2;
}else {
echo $initial_post;
echo value1;
echo value2;
}
?>
使用此方法,还有一个优点,即您可以通过将表中的isModerated值从1更改为0来轻松回滚审核
答案 4 :(得分:2)
想法:为所有表添加修订号。当有人进行更改时,此更改的唯一修订号将存储在所有受影响的行中。而不是更新,插入具有更高版本号和相同ID的行。当然,Id列不能设置为唯一。当前活动的修订号存储在仅保存此编号的表中。然后生成看起来像前面的表的DB视图,但如果2行具有相同的id,则它只获得具有与活动修订版相等或更低的最高版本号的条目。在您的应用中,您使用视图而不是原始表。 然后,您可以查看原始表中的更改,删除不接受的更改,并提升当前活动的修订以接受尚未删除的所有更改。
答案 5 :(得分:2)
您可以为表添加修订并拥有复合主键
假设您有此表
id -> Integer PK
comment -> text
user -> integer
如果添加此字段
revision -> integer PK with id
published -> boolean -- this will tell you wich one is active
您可以添加更多审核字段,例如某些日期以检查创建新修订的时间或创建修订的人员
并且登录获取版本很简单,您可以通过其版本号选择任何修订版,或者您可以获得活动版...
当然,这会给你一些麻烦的问题(2个人同时修改同一行...但你可以使用信号量,或类似的东西),你不能继续使用发电机/自动补偿你的insert,(好吧,你只能使用生成器来获取新记录)。
另一种方式是,如果您不想存储所有更改历史记录,并且只需要最后一个版本,则添加文本字段,并使用编辑的值保存序列化数组,并且当您批准时,只需运行更新字段。
有很多方法,你可以使用这个序列化的aproch并使用aux表来保存历史记录,并混合aproche,在aux表中放入原点id,修订版和序列化数组,然后你同时拥有......所有版本的序列化版本......
选择最能描述你情况的人......答案 6 :(得分:1)
另一个想法是将所有已更改的数据存储在一个数组中(array [$ table] [$ field] [$ id] = $ value),然后将其存储在一个带有TEXT类型字段的简单表中,采用json编码。这样,您还可以灵活地更改(添加)其他控件,而无需更改编辑表结构。 : - )
答案 7 :(得分:1)
我认为如果您认为没有任何 GOOD 选择,您可以轻松地向后工作并找出最差选项以查看最不好的选择。每个选择都需要牺牲。但是有什么牺牲?
选项#1 :复制所有表格(将MyTable和MyTable_ToApply放在一起)。
IMO这将是一个巨大的头痛。谈论太多的领域!您还需要创建额外的编码,以便将数据从一个表移动到另一个表。我认为这里有太多可能出错的地方。
选项#2 :添加一个包含四个字段的特殊表(ToApplyTable
):要修改的表,要修改的字段,要修改的条目的ID以及新值申请。
我认为这也是一个肮脏的选项,正如你所提到的,因为同样的事情 - 将值从一个表移动到另一个表。
选项#3 :将date
和ismoderated
值添加到表格中。
许多人都提到过这一点。你的论点是它太多(通常是无用的)列。我认为这比其他任何提到的要好。我将谦卑地提出一个最终方法,它是选项#1和选项#3的组合。
选项#4 :在每个可以拥有审核字段的表下创建自定义ismoderated
表。
我在我的数据库中执行类似的操作并使用命名标准[TABLENAME]__ismoderated
。在此表中,如果只需要一个列,则实际上不需要多个列。您可以在此需要审核的项目表中使用外键,然后在最终审核后删除该密钥。或者,您可以在此处添加主持人的用户ID,并在需要时添加作为附加字段的时间。
我个人认为我也会使用datetime字段,因此您可以跟踪更改并知道哪一个是最新的。
无论如何,这使您能够INNER JOIN
两个表。如果您只想查看要审核的值。
答案 8 :(得分:1)
已经给出了很多答案,我觉得大多数都是非常合理的。我相信有一些很好的方法可以做到这一点。
我假设处理能力/速度比HDD和RAM中的存储空间更重要/更昂贵。 我也同意Robbes先生(我上面的某个地方)每行/单元应该有一个修订版,并且添加额外的列不是正确的解决方案(参见下面的详细说明)
让我首先从我认为不正确的选项开始:
查看问题中给出的事实:
我认为您提供的第二个解决方案最适合您的数据。
可以通过多种方式对用户进行修订。使用上面的临时表/视图,您使用存储过程来更改表中的内容(或将单元格设置为“活动”并更新临时表/视图) 您可以简单地用新的行替换数据库中的行(虽然更新很昂贵),或者使用连接构造。
如果CPU比存储便宜,那么查看具有哈希值的类似git的系统可能会有效。
答案 9 :(得分:0)
然而,主持人将使用表格更改数据..
当他们更改数据时,为什么不将数据保存在csv文件中...
修改更改时,可以插入实际表格中。
它只是一个想法..