Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 这是1NF故障吗?_Php_Mysql_Sql_Database_Normalization - Fatal编程技术网

Php 这是1NF故障吗?

Php 这是1NF故障吗?,php,mysql,sql,database,normalization,Php,Mysql,Sql,Database,Normalization,考虑到1NF故障,没有重复的元素组,如果您想对重复组的数量设置限制,该怎么办 例如,您希望学生只列出3个电话号码。没有了。有如下表格会被视为1NF故障吗 Student 1 Phone1 Phone2 Phone3 Sally 111-1111 222-2222 333-3333 John 555-5555 999-9999 NULL 您将创建一个限制。这是可接受的、高效的数据库设计吗 像1NF故障一样,将电话号码放在单独的表格中是否更好

考虑到1NF故障,没有重复的元素组,如果您想对重复组的数量设置限制,该怎么办

例如,您希望学生只列出3个电话号码。没有了。有如下表格会被视为1NF故障吗

Student 1    Phone1    Phone2    Phone3
Sally        111-1111 222-2222   333-3333
John         555-5555 999-9999   NULL
您将创建一个限制。这是可接受的、高效的数据库设计吗


像1NF故障一样,将电话号码放在单独的表格中是否更好?如果在单独的表中,您将如何创建每个用户3个数字的限制

不,它不是标准化的。当存在空值时,您将浪费表中的空间,如果您想搜索特定的电话号码,则必须搜索所有三列。而是使用一个单独的表(例如StudentPhoneNumber)来存储它们。如果您想将其限制为三个,请使用触发器防止每个学生超过三个。

1NF禁止连续重复列表。您的设计违反了这一点,以下设计也违反了这一点:

Student     Phones
'John D'    '555-5555, 666-6666, 777-7777'
'Sally S'   '111-1111, 222-2222'
以下设计将违反2NF,因为唯一的主键是
Name,Phone
,但
Address
属性不依赖于
Phone

Name        Phone       Address
'John D'    '555-5555'  '1 Square Village'
'John D'    '666-6666'  '1 Square Village'
'John D'    '777-7777'  '1 Square Village'
'Sally S'   '111-1111'  '999 Flash City'
'Sally S'   '222-2222'  '999 Flash City'
下一个设计将违反3NF,因为AreaName不依赖于名称,而只依赖于面积:

Name        Area    Phone   AreaName
'John D'    '555'   '5555'  '111name'
'John D'    '666'   '6666'  '666name'
'John D'    '777'   '7777'  '777name'
'Sally S'   '111'   '1111'  '111name'
'Sally S'   '222'   '2222'  '222name'
即使您的设计违反1NF,这也是一个很好的选择。添加
PhoneNumber
表的复杂性几乎没有道理

想一想,如果您遵守1NF,对客户进行更新会有多困难。数字将在单独的表格中。因此,如果有人提交了一份带有更新电话号码列表的表单,您将如何更改数据库?首先,您必须检索现有的数字列表。然后,您必须将它们与提交的列表进行比较。然后,您必须根据差异删除或插入行。一个非常复杂的解决方案


如果您坚持您的解决方案,您可以只更新三列。节省的时间可以花在真正的功能上!或者甚至在堆栈溢出上写长答案。

user1122200,让我们假设您的数据库设计有所增长。您需要为每个电话号码分配特定的数据(如电话位置:'房子','工作',…)。在这种情况下,你会渴望一个电话桌。此外,假设您需要从电话号码(如有人打电话时必胜客或出租车服务)中查找学生,则在规范化设计良好的情况下,此查询更容易:

select *
from students
where 
  Phone1 = '91112223' or
  Phone2 = '91112223' or
  Phone3 = '91112223'
您的关系变量(relvar)确实违反了1NF,但可能不是因为您期望的原因:是null的存在违反了1NF。如果您认为您的relvar包含一个重复组,请三思

第一种范式,或者简单的“规范化”,是关系模型的最低要求。引用Chris Date的话:

根据定义,null不是一个值。它是这样的:一种 包含null不是类型(因为类型包含值);“元组” 包含null的不是元组(因为元组包含值);A. 包含null的“关系”不是关系(因为 包含元组,元组不包含空值)。事实上,空值 违反最基本的关系原则,即 信息原理。所有这些的净结果是如果空值 现在,我们当然不是在讨论关系模型 (我不知道我们在谈论什么,但这不是关系 模型);整个大厦都倒塌了,所有的赌注都输光了

关于重复分组和1NF的观点很难解释,我不会尝试。相反,我敦促你们阅读,特别是“重复群体的模糊性”一节

假设空值被消除,relvar将满足1NF,但请注意,我们需要进一步的信息(例如键)来确定它是否也满足更高的范式

如果在单独的表中,您将如何创建每个用户3个数字的限制

我假设一个学生可能有零个、一个、两个或三个电话号码

如果您的SQL产品支持完整的SQL-92:

CREATE TABLE Students
(
 student_name VARCHAR(20) NOT NULL UNIQUE
);

CREATE TABLE StudentPhonebook
(
 student_name VARCHAR(20) NOT NULL
    REFERENCES Students (student_name), 
 phone_number CHAR(8) NOT NULL
    CHECK (phone_number LIKE '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]'), 
 UNIQUE (student_name, phone_number)
);

CREATE ASSERTION students_max_three_phone_numbers
   CHECK (
          NOT EXISTS (
                      SELECT *
                        FROM (
                              SELECT student_name, COUNT(*) AS tally
                                FROM StudentPhonebook
                               GROUP 
                                  BY student_name
                             ) AS DT1
                       WHERE tally > 3
                     )
         );
MySQL不支持任何风格的
CHECK
,也没有SQL产品支持
CREATE ASSERTION
,因此上述约束必须使用过程代码编写,例如触发器

出于兴趣,如果您的SQL产品支持行级
检查
约束(与大多数SQL产品一样),则可以使用
出现
属性和
介于1和3之间的约束,然后将此属性包含在关键约束中,例如

CREATE TABLE StudentPhonebook
(
 student_name VARCHAR(20) NOT NULL
    REFERENCES Students (student_name), 
 phone_number CHAR(8) NOT NULL
    CHECK (phone_number LIKE '[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]'), 
 occurrence INTEGER DEFAULT 1 NOT NULL
    CHECK (occurrence BETWEEN 1 AND 3), 
 UNIQUE (student_name, phone_number), 
 UNIQUE (student_name, occurrence)
);

不是2NF或3NF格式,而是1NF格式,这就是OP要问的。@user1122200-为什么要问SQL Server?你已经标记了MySQL?@user1122200-你似乎太敏感了。我没有批评过这个问题。如果使用中的1NF有不同的定义(Codd与日期),那么这肯定是相关的。你似乎忽略了其中的一部分,即如果你使用Date的定义,这是一种违反。这显然是一场高度学术性的辩论。归根结底,答案就是“不要这样做”。为什么在第一、第二或第三个NF时这是一个坏主意真的很重要?这仍然是一个坏主意。@user-您还可以通过在
StudentId,Number
上设置唯一约束,并在
Number
上设置检查约束,以声明方式管理此约束,强制将其设置为
1,2,3
。使用起来仍然不是那么容易,但由于RDBMS强制执行,它可以避免由于触发代码中的竞争条件而超过
3
限制。这需要支持检查约束的RDBMS。MySQL没有。因此,似乎即使重复组的数量有限制,1NF故障也可能发生,而不仅仅是针对没有设置限制的重复组。实际上,您只需删除他所有的电话号码,然后从表单中插入所有-或