使UNIQUE KEY与查询关系

时间:2014-06-23 16:01:06

标签: mysql sql database relational-database database-schema

这听起来很奇怪,我知道。这是一个解释:

1-我有下表 - 项目(由于用户可以更新项目数量及其中的内容,因此会更新):

| id         | content     | item_id      | Order (Unique Index)|
|:-----------|------------:|:------------:|:--------------------:
| 1          |        This |     1        |     1
| 2          |          is |     1        |     2
| 3          |     content |     1        |     3

| 4          |        Some |     2        |     1
| 5          |        More |     2        |     2

| 6          |       More! |     3        |     1

2-在我的服务器上,我正在运行一个查询,它将遍历我的POSTed内容,根据其item_id检查每个项目,以及检查该行中的订单是否已设置。 如果设置了订单,则更新内容,否则插入新内容

让我们说我的内容是POST 4项,item_id = 1.最好是我希望它做什么

| id         | content     | item_id      | Order (Unique Index)|
|:-----------|------------:|:------------:|:--------------------:
| 1          |        This |     1        |     1
| 2          |     updated |     1        |     2
| 3          |     content |     1        |     3

| 4          |        Some |     2        |     1
| 5          |        More |     2        |     2

| 6          |       More! |     3        |     1

> 7          |       added |     1        |     4

注意发生的事情是,它添加了一个新行,因为我的POSTed内容中有四个项目。它迭代了每一个,检查订单是否存在,如果订单存在,则更新值,否则创建一个新行并插入值以及订单(键)。订单几乎是关键。这就是我在那里设置它的方式。

当我这样做时它不起作用:

// Start loop  - for (key in content) {
INSERT INTO items (item_id, content, content_order) VALUES (?, content[key], ?) WHERE item_id = ? ON DUPLICATE KEY UPDATE content = ?
// End loop

循环正在做什么,它遍历POST的所有内容并将其插入数据库,如果有重复的密钥(在这种情况下,唯一索引是Order列)然后只更新其中的内容。

问题是,它只能用于前三项。为什么?因为前三项是具有这些唯一索引的第一项。如果我要更新item_id为2的项目,那么它会给我一个错误,因为我无法更新具有相同唯一键的项目。我甚至无法插入任何内容,因为它违反了唯一索引限制!

那我怎么能这样做呢?

  • 有没有办法让查询的绝对唯一索引 - 这意味着它只会记住基于查询指定的item_id的唯一索引? (怀疑它)

  • 如何设置它以检查订单是否已设置并更新内容或插入新行而不使用唯一键?

  • 有没有其他方法可以写这个?

如果需要详细说明,请告诉我。感谢。

1 个答案:

答案 0 :(得分:0)

根据您的需求进行直接设计可能没有任何问题。虽然你的问题不清楚,特别是关于新内容。

订单不是商品的关键。因为列顺序不是唯一的。你想要的关键是(item_id,order)。

你需要物品ID吗?我会忽略它。我会将新内容视为表格中的内容。您可能应该从中构建一个常量子查询。是否所有新内容item_ids都显示在商品中?

<强> 1。没有NULL。

一个简单的设计是拥有一个名为内容的项目版本,其中包含使以下填充空白语句成立的行。我假设商品订单在item_id中是连续的。

// item [item_id]'s [order]th content is [content]
content(item_id,order,content)
    primary key (item_id,order)

我会猜测你的新内容格式和效果。我假设订单在item_id中从1开始是连续的。我将替换新内容item_id的所有内容信息。

// item [item_id]'s [order]th content is [content]
more_content(item_id,order,content)
    primary key (item_id,order)

delete from content
    where item_id in (select item_id from more_content)
insert into content
    select * from more_content

<强> 2。空值

如果NULL顺序表示没有内容,则可以改为内容为NULL且order = 1。 (你也可以有另一个表,没有NULL。)如果NULL顺序表明默认值没有改变,那么只需要另一个表:

// item [item_id]'s content is a default
has_default(item_id)
    primary key (item_id)

delete from has_default
    where item_id in (select item_id from more_content)

delete from content
    where item_id in (select item_id from more_content)
insert into content
    select * from more_content

如果您想要按原样阅读项目,请查看:

//     [order] is null AND item [item_id]'s default content is [content]
// OR [order] is not null AND item [item_id]'s [order]th content is [content]
create view items as (
    select c.item_id,c.content,if(d.item_id is null,c.ord,NULL) as ord
    from content c left join has_default d on c.item_id=d.item_id
    )

很难弄清楚你的设计。

在SQL中为您的需求实现任何设计的约束可能很困难。但是你应该从一个简单的设计开始。