对于在发送之前自动保存电子邮件或在完成或正式保存之前保存博客文章的应用程序的最佳策略是什么?最好在数据库中为临时草稿使用单独的表,还是使用状态列将帖子标记为草稿或已发布?我不是在寻找代码,只是在寻找方法,但也欢迎任何其他相关的建议,比如多久保存一次等。
3 回答
考虑到草稿和已发表文章的单独表格基本上是相互重复的,我倾向于只使用一个带有状态列的表格来区分两者。
我按照维基百科的方式起草:我保存第一个版本,所有修改都保存(基于时间或明确的用户命令)作为下一个版本。即之后。您可以删除草稿图 - 或不删除。
如果您将数据保存在数据库中,我认为最好使用同一张表(可以避免模式冲突),并使用版本/状态来跟踪草稿生命周期。
这不仅适用于电子邮件...
我改变了主意。最好的方法是在表中使用 is_draft 列,并将草稿和有效实体存储在同一个表中。这具有实体保持相同 id 的优点,即使它切换到草稿状态(您可能希望在保存后对其进行编辑,但暂时删除所需的值)。如果他们在同一个文档上进行协作并且 id 不断变化,那会让用户感到困惑,amirite?
您将使用 is_draft=1 关闭 ORM 验证规则、触发验证或检查约束以允许保存无效对象。是的,您可能必须在表中允许可为空的字段。
过程:尝试保存对象。验证失败。设置 is_draft=1 并尝试再次保存。它可以节省。把大的“草稿”放在屏幕上的某个地方:)
用户填写所需信息。尝试保存对象。验证通过。设置 is_draft=0。它可以节省。
现在,关于电子邮件和博客文章,除非用户点击保存/发布按钮,否则您的服务器不应尝试立即发送或发布,但这确实是一个不同的问题。
旧答案
问题是草稿可能无效,并且无法保存在实际表中。例如,假设您的表格要求主题不为空,但用户尚未填写。
一种方法是拥有一个草稿表,并将实体(及其子项)的序列化版本存储到其中。php 的 serialize() 可以使用,或者你可以使用 json。当它最终有效时,系统将改为保存到电子邮件(或其他)表中,并删除草稿:
伪sql:
create table draft
id int primary key auto increment,
entity varchar(64) not null comment 'this way you can find all drafts of say type Email',
contents longblob not null,
modified timestamp comment 'this way you can sort by newer drafts'
modified_by int not null foreign key to user.id comment 'this way you can filter by the user\'s drafts'
您还可以考虑使用 draft_file 表来存储草稿的附件或照片,并能够单独访问它们:
create table draft_file
id int primary key auto increment,
draft_id int not null foreign key to draft.id on delete cascade,
size int not null comment 'bytes',
mime_type varchar(64) not null,
file_name varchar(255) not null,
contents longblob,
thumbnail blob comment 'this could be an icon for files/documents'
因此,用户开始撰写电子邮件,可能只是在正文中输入内容,并添加一些附件。您的 gui 将电子邮件保存到草稿,并上传附件,将它们保存到 draft_file,并返回草稿 ID,以及您在 gui 中显示的文件的下载 url。
他输入主题(To 仍为空白)。您的 gui 将电子邮件保存到草稿中,通过 id 更新草稿表,因为它从上一步中知道其 id。
您的用户填写“收件人”字段,然后点击“发送”。您的服务器将电子邮件保存到 email 表,将附件从 draft_file 复制到 email_attachment 表,并删除草稿,最好在事务中删除。
这允许长期草稿、gmail 样式的附件上传,同时保持真实实体表的完整性。