简体   繁体   English

mysql创建发布并将图像和段落存储在单个表或多个表中

[英]mysql create post and store images & paragraphs in single table or multiple table

I try to build a post article page contain images and paragraphs. 我尝试建立一个包含图像和段落的文章页面。

My question is should I create 2 tables for images and paragraphs? 我的问题是我应该为图像和段落创建2个表格吗?

or create a single table and store images & paragraphs in one column? 或创建一个表并将图像和段落存储在一个列中?

*(images & paragraphs will have order from top to bottom) *(图片和段落从上到下的顺序)

1. multiple table 1.多表

//article table //文章表

id title
1  first post

//image table (easy to output, but db will become very big) // image表(易于输出,但是db会很大)

id article_id src
1  1          abc.jpg

//paragraph table //段落表

id article_id text
1  1          this is first paragraph...

2. single table (store tag inside db, output will have xss problem) 2.单表(在db内存储标签,输出会有xss问题)

//article table //文章表

id  content
1  <p>feff.....</p><img... /><p>efefef</p><img.../>

The problem with your first approach is that it has no concept of order. 您的第一种方法的问题在于它没有顺序的概念。 Unless you only have one image and one paragraph in a specific order there's no way to guarantee the correct order. 除非您只有一个图像和一个段落以特定顺序排列,否则无法保证正确的顺序。 A better approach to such a task would be to have something like articles and article_contents . 完成这些任务的一种更好的方法是将有类似articlesarticle_contents

// articles //文章

id, title

// article_contents // article_contents

id, article_id, content_type, body, order

I suppose you could also not have the order field and rely on auto increment ID but I think it's better to be more explicit with these things. 我想您也可能没有order字段,而是依靠自动增量ID,但是我认为最好对这些内容更明确。

So when rendering the the template you can do something like. 因此,在渲染模板时,您可以执行类似操作。 (this is all pseudo code) (这都是伪代码)

<h1>
    <?= $article->title; ?>
</h1>

<?php
foreach($article->content as $content) {
    // this would be better as a class constant
    if ($content->content_type === 'image') {
        // have a class to handle rendering of images
        echo \Content\Image::render($content->body);
    }

    if ($content->content_type === 'paragraph') {
        // have a class to handle rendering of content, this output will likely need to be purified (see below)
        echo \Content\Paragraph::render($content->body);
    }
}
?>

There are lots of ways you could do it. 有很多方法可以做到。

The other option you mentioned does have issues but you can handle the XSS issue one of two ways. 您提到的另一个选项确实有问题,但是您可以通过两种方式之一来处理XSS问题。

  1. htmlentities() but then you lose all formatting (). htmlentities(),但您会丢失所有格式()。
  2. HTML Purifier, this will allow you to whitelist certain tags like bold, italic and paragraph. HTML Purifier,这将使您可以将某些标签(如粗体,斜体和段落)列入白名单。 You will also likely need to do this for the first solution as well because articles are pretty awful to read without any formatting. 对于第一种解决方案,您也可能需要这样做,因为没有任何格式的文章阅读起来很糟糕。

Updates based on comments: 基于评论的更新:

In regards to your first comment, you can't rely on the IDs if the IDs are in two separate tables, it might work but it's a very fragile solution that doesn't offer any benefit I can think of. 关于您的第一条评论,如果ID位于两个单独的表中,则不能依赖ID,它可能会起作用,但这是一个非常脆弱的解决方案,没有提供我能想到的任何好处。

As for purifying src tags, you just have to configure HTMLpurifier to validate src tags, from the looks of it you can do that with the directive Core.RemoveInvalidImg . 至于净化src标记,您只需配置HTMLpurifier即可验证src标记,从外观上,您可以使用指令Core.RemoveInvalidImg HTMLPuirifier has a LOT of these options built in, it's very powerful. HTMLPuirifier内置了很多这些选项,功能非常强大。 See the links bellow for more options/documentation. 有关更多选项/文档,请参见下面的链接。

https://github.com/GordonLesti/Lesti_Blog/tree/master/lib/HTMLPurifier/ConfigSchema/schema https://github.com/GordonLesti/Lesti_Blog/tree/master/lib/HTMLPurifier/ConfigSchema/schema

http://htmlpurifier.org/docs/enduser-customize.html http://htmlpurifier.org/docs/enduser-customize.html

Further updates: 进一步更新:

In regards to the performance. 关于性能。 That's what is known as "a good problem to have". 这就是所谓的“要解决的好问题”。

When selecting articles you can cache the resulting HTML and serve that, there's no need to bother the database when the data doesn't change frequently. 选择文章时,您可以缓存结果HTML并将其提供,当数据不经常更改时,无需打扰数据库。

When inserting new articles, you just need to wait and build around it. 插入新文章时,您只需要等待并围绕它构建即可。 You can do things like update the UI and update the database asynchronously. 您可以执行诸如更新UI和异步更新数据库之类的操作。 Keep the user informed, that's the most important thing. 让用户了解最新信息,这是最重要的。

When updating articles don't forget to invalidate the cache. 更新文章时,请不要忘记使缓存无效。

The main thing to take away though is, that's not really a problem you need to think about right now . 最主要的是, 这不是您现在需要考虑的真正问题 Throw a caching layer in now and when you get to the size of SO then you can employ people who are specialists to handle that kind of crazyness. 现在,请放入一个缓存层,当您达到SO的大小时,您可以聘请专业人士来处理这种疯狂的事情。 See the link below, it's very interesting. 请参阅下面的链接,这非常有趣。

http://nickcraver.com/blog/2013/11/22/what-it-takes-to-run-stack-overflow/ http://nickcraver.com/blog/2013/11/22/what-it-takes-to-run-stack-overflow/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM