【问题标题】:MySQL disallow row that has 2 identical column values with another rowMySQL 不允许具有 2 个与另一行相同的列值的行
【发布时间】:2011-07-28 10:20:51
【问题描述】:

这是我的 MySQL 表:

  • 左列自动递增。
  • 中间列是用户的 id#。
  • 右栏是他们喜欢的帖子的 ID#。

我正在向表中插入数据,如下所示:

$stmt = $db->prepare("INSERT INTO likes (user_id,post_id) VALUES (?,?)");
$stmt->execute(array($_SESSION['user'],$_POST['id']));

这很好用,但是正如您所见,MySQL 表有两个相同的行(id 的 3 和 4),它们的 user_id 为 5,post_id 为 196。换句话说,我的 MySQL 表记录了具有 id 的用户= 5 喜欢 id = 196 的帖子 两次。 我如何禁止存在两行具有相同 user_id 相同 post_id 的情况

【问题讨论】:

  • 您需要自动递增id 列吗?我只想在user_id,post_id 上进行复合 PK
  • @Martin @inquisitive 很少有不需要 ID 列的情况,这肯定不是那种情况。 See this question and answer
  • @rockerest - 您似乎将PKId 列混淆了。它们不是同一件事。我建议 OP 在 2 列上有一个复合主键。
  • @martin,很明显id 是他的PK
  • @rockerest - 但目前还不清楚id 列是否有任何有用的目的(我怀疑它没有)。我建议放弃它并在超过 2 列上创建一个复合主键。

标签: php mysql


【解决方案1】:

您需要在 user_id 和 post_id 列上设置unique constraint

【讨论】:

  • 这是错误。 UNIQUE 约束只允许用户“喜欢”一件事。曾经。不要这样做。
  • @rockerest - 完全不正确。唯一约束can be on multiple columns.
  • 我的意思是跨越两列。实际上你可能需要一个索引 - 见stackoverflow.com/questions/635937/…
  • 太好了,谢谢。我刚开始工作。 ...我有点慢。
【解决方案2】:

更新

下面的答案可能会导致Race Conditions,并且在某些情况下可能会出现重复的数据库条目。

感谢@Martin 发现以下系统的主要缺陷:


这是您在业务逻辑中应该做的事情。我实现一个几乎相同的系统的方式是这样的(在伪代码中):

Show Blog/Video/Post/Etc.

Has user "liked" this?
    Yes = show "unlike" button (on server, not JS)
    No  = show "like" button (on server, not JS)

Add or delete "like" as necessary

显示任一按钮的代码在服务器上,因此用户无法拦截它并手动选择要执行哪个按钮。

唯一的缺陷是必须有一种方法来识别用户单击了哪个按钮,这意味着用户可能会花费大量时间挖掘和摆弄,并可能更改页面上的按钮/链接/任何内容。

我通过在服务器上测试用户是否已经喜欢,然后仅在他们不喜欢时才插入来克服这个问题。

【讨论】:

  • 强制唯一约束应该在数据库中完成。在其他任何地方,您都会获得竞争条件和重复。
  • @martin,你能解释一下吗?我不清楚在这种情况下如何获得竞争条件或重复。
  • 如果我向您的服务器提交多个请求,那么 2 个并发事务都可以检查该行是否存在并找到它不存在并继续进行插入。在数据库中拥有唯一的约束也是一件好事,因为查询优化器可以利用这些知识来制定更有效的查询计划。
【解决方案3】:
CREATE UNIQUE INDEX user_post on likes (user_id, post_id)

这可以防止多次使用相同的 (user_id, post_id) 值...

【讨论】:

    猜你喜欢
    • 2012-05-25
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 2017-02-14
    • 1970-01-01
    • 1970-01-01
    • 2018-07-14
    • 2015-11-03
    相关资源
    最近更新 更多