0

可以在 中使用 'NULL' 值deal.tariff_id来表示它属于tariff_data表中的任何关税affiliate_id=3吗?

例如:

mysql> select * from phone;
+----+------------------+
| id | name             |
+----+------------------+
|  4 | HTC Sensation XL |
| 26 | iPhone 4s        |
| 25 | iPhone 5         |
| 24 | Nokia C3-01      |
+----+------------------+

mysql> select * from tariff;
+----+-----------------+-----------------+--------------+-------------+
| id | name            | tariff_duration | monthly_cost | description |
+----+-----------------+-----------------+--------------+-------------+
|  1 | Business Plan 1 |              24 |         5.00 |             |
|  2 | Business Plan 2 |              24 |        10.00 |             |
|  4 | Business Plan 3 |              24 |        15.52 |             |
|  5 | Business Plan 4 |              24 |        18.52 |             |
|  8 | Super Plan      |              12 |        15.00 |             |
+----+-----------------+-----------------+--------------+-------------+

mysql> select * from tariff_data;
+----+-----------+--------------+-------+
| id | tariff_id | affiliate_id | bonus |
+----+-----------+--------------+-------+
|  1 |         1 |            3 | 34.00 |
|  2 |         2 |            3 | 44.00 |
|  5 |         3 |            3 | 10.00 |
|  6 |         4 |            3 | 10.00 |
|  7 |         5 |            3 | 10.00 |
+----+-----------+--------------+-------+

在一张deal表上,您可以看到affiliate_id=3tariff_id=NULL属于tariff_data表中列出的任何关税。我这样做是为了减少deal. 如果我不包含 NULL ,则意味着我必须包含许多tariff_id相同的内容phone_id,反之亦然。

mysql> select * from deal;
+----+----------+-----------+--------------+--------+
| id | phone_id | tariff_id | affiliate_id | active |
+----+----------+-----------+--------------+--------+
|  1 |        4 |      NULL |            3 |      1 |
|  3 |       24 |      NULL |            3 |      1 |
|  9 |       24 |         8 |            4 |      1 |
| 10 |       25 |         8 |            4 |      1 |
| 11 |       26 |         8 |            4 |      1 |
+----+----------+-----------+--------------+--------+

更新,例如,如果我没有使用 NULL 值:

mysql> select * from deal;
+----+----------+-----------+--------------+--------+
| id | phone_id | tariff_id | affiliate_id | active |
+----+----------+-----------+--------------+--------+
|  1 |        4 |         1 |            3 |      1 |
|  2 |        4 |         2 |            3 |      1 |
|  3 |       24 |         1 |            3 |      1 |
|  4 |       24 |         2 |            3 |      1 |
|  5 |       24 |         3 |            3 |      1 |
|  6 |       24 |         4 |            3 |      1 |
|  7 |       24 |         5 |            3 |      1 |
|  9 |       24 |         8 |            4 |      1 |
| 10 |       25 |         8 |            4 |      1 |
| 11 |       26 |         8 |            4 |      1 |
+----+----------+-----------+--------------+--------+
4

5 回答 5

2

有许多方法可以实现所需的结果,但使用比 NULL 更合乎逻辑的方法。

正如 Oded 指出的那样,NULL 表示缺少未知值

  • 可能有一个列来指示所有权
  • 正常化
  • 使用现有列“tariff_id”作为具有 NON NULL 值的所有权指标
于 2012-10-06T20:20:42.873 回答
1

不是一个好主意。

NULL表示未知值。情况并非如此,使用它来具有特定含义会反过来咬你。

首先,任何接触系统部分(代码和 SQL)的人都必须知道并记住该约定。

其次,它是不可扩展的——如果你需要一些东西来代表所有affiliate_id4 的 tarrifs 怎么办?

第三——如果你真的需要使用,你会怎么做NULL

于 2012-10-06T20:00:26.010 回答
1

与其他两个答案一样,这不是一个好主意。这是规范化的建议。

您希望某些交易代表“一般”交易,而不考虑关税。您可以将 deail 表拆分为两个,一个用于简单交易,一个用于一般交易:

mysql> select * from deal_simple;
+----+----------+-----------+--------------+--------+
| id | phone_id | tariff_id | affiliate_id | active |
+----+----------+-----------+--------------+--------+
|    |       24 |         8 |            4 |      1 |
|    |       25 |         8 |            4 |      1 |
|    |       26 |         8 |            4 |      1 |
+----+----------+-----------+--------------+--------+

mysql> select * from deal_general_tariff;
+----+----------+--------------+--------+
| id | phone_id | affiliate_id | active |
+----+----------+--------------+--------+
|    |        4 |            3 |      1 |
|    |       24 |            3 |      1 |
+----+----------+--------------+--------+

然后,您可以使用简单查询获得扩展结果(我假设您没有错误地包含与 相关的 3 行phone_id 4tariff_id 3, 4, 5

SELECT phone_id, tariff_id, affiliate_id, active
FROM deal_simple

UNION

SELECT dgt.phone_id, td.tariff_id, dgt.affiliate_id, dgt.active
FROM 
    deal_general_tariff AS dgt
  JOIN 
    tariff_data AS td
      ON td.affiliate_id = dgt.affiliate_id ;
于 2012-10-06T22:47:29.313 回答
1

不是一个好主意。基本问题是 NULL 已经意味着三个不同的东西,这使它们成为问题。你在问问题。它代表的是:

  1. 未知值(即未输入,预期存在)。这意味着 NULL || 'mytext' 为空。
  2. 已知不存在的值(例如,在街道地址的第二行使用 NULL)。这是有问题的,但很难避免。在非 Oracle 平台上,空字符串在这里更适合字符类型。看起来你正在称这个重量。
  3. 在外连接的结果中未找到值

这意味着在处理 NULL 值时,您已经准备好三种不同的情况,并且您必须使用上下文来解决它。如果您可以将含义减少到两个,或者更好的是 1(外部连接未找到记录),那么您的情况会更好,并且您需要担心的情​​况更少。

当一个人预期存在两个值之一时,问题当然必须解决,例如employee.hourly_wage 或employee.monthy_salary。这当然是一个不好的例子,因为可以做工资或工资加上工资单位,但问题很普遍。很多时候,您必须在完美规范化和避免列中的空值和另一方面丰富的跨列数据约束之间进行权衡。

于 2012-10-07T05:20:19.343 回答
0

不要使用 NULL 来传达消息。使用 NULL 表示没有值。

缺少值可能意味着存在值,但未知。此案由 Oded 报道。

这也可能意味着某个值在这种情况下不适用。当表包含描述给定类的对象的行时,通常会发生这种情况,但有多个子类扩展了该类。某些列可能与某些子类有关,但与其他子类无关。

如果需要,您可以通过一种在 SO 中具有名为“类表继承”的标记的技术来解决最后一种情况。

如果数据的读者从缺乏价值中得出推论,他们可以。但推理不是交流。

于 2012-10-07T12:35:26.583 回答