Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.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
规范化MySQL数据_Mysql_Normalization - Fatal编程技术网

规范化MySQL数据

规范化MySQL数据,mysql,normalization,Mysql,Normalization,我是MySQL新手,刚刚了解了数据规范化的重要性。我的数据库有一个简单的结构: 我有一个名为users的表,其中包含字段: userName (string) userEmail (string) password (string) requests (an array of dictionaries in JSON string format) data (another array of dictionaries in JSON string format) deviceID (string

我是MySQL新手,刚刚了解了数据规范化的重要性。我的数据库有一个简单的结构:

我有一个名为
users
的表,其中包含字段:

userName (string)
userEmail (string)
password (string)
requests (an array of dictionaries in JSON string format)
data (another array of dictionaries in JSON string format)
deviceID (string)
现在,这是我的结构。作为MySQL的新手,我真的不明白为什么我的上述结构是个坏主意?为什么我需要对此进行规范化并创建单独的表?这是第一个问题为什么?(有些人还说不要把JSON放在我的表中。为什么

第二个问题是如何解决?使用上述结构,我应该有多少个表,每个表中应该有什么

编辑:
所以,也许规范化在这里不是绝对必要的,但也许有更好的方法来实现我的数据字段?
data
字段是一个字典数组:每个字典只是一个带有几个键(标题、作者、日期、正文)的注释项。所以我现在做的是,我认为这可能是低效的,每次用户编写一个新的便笺时,我都会将该便笺从我的应用程序发送到PHP来处理。我得到的JSON字典数组已经是该用户数据的一部分,我将其转换为PHP数组,然后在该数组的末尾添加新注释,将整个内容转换回JSON,并将其作为字典数组放回表中。每次创作新音符时,这个过程都会重复。有更好的方法吗?也许用户的数据应该是一个表,每一行都是一个注释,但我不确定这将如何工作?

规范化是一种理念。有些人认为它适合他们的数据库方法,有些人则不适合。许多现代数据库解决方案甚至关注非规范化以提高速度

正常化通常不能提高速度。但是,它大大提高了访问和写入数据的简单性。例如,如果要添加请求,则必须编写一个全新的JSON字段。如果它是标准化的,您可以简单地向表中添加一行

在规范化中,“JSON字符串格式的字典数组”总是不好的。字典数组可以翻译为行列表,这是一个表


如果您是数据库新手:规范化。反规范化是专业人士的事情。

所有问题的答案实际上取决于JSON数据的用途,以及您是否需要使用该数据的某些属性来确定返回哪些行

如果您的数据确实没有模式,并且您实际上只是使用它来存储数据,而应用程序每次都知道如何通过某些其他条件(如其他字段之一)检索正确的行,那么没有理由将其存储为应用程序所期望的以外的任何内容(在本例中为JSON)

如果JSON数据确实包含一些对所有条目都相同的结构,并且如果直接从数据库查询这些数据很有用,那么您需要创建一个或多个表(或者可能只是一些字段)来保存这些数据

作为一个实际示例,如果数据字段在数组中包含该用户的JSON枚举服务,并且每个服务都有唯一的id、类型和价格,那么您可能需要一个包含以下字段的单独表(使用您自己的命名约定):

每个用户的服务都有自己的条目。然后,您可以查询具有特定服务的用户,这取决于您的需要,可能非常有用。除了简单的查询之外,为单独表的某些字段编制索引也可以实现非常快速的查询

更新:根据您对存储数据的解释和使用方式,您可能确实希望将其规范化。如下所示:

# user table
userId (integer, auto-incrementing)
userName (string)
userEmail (string)
password (string)
deviceID (string)

# note table
noteId (integer, auto-incrementing)
userId (integer, matches user.userId)
noteTime (datetime)
noteData (string, possibly split into separate fields depending on content, such as subject, etC)

# request table
requestId (integer, auto-incrementing)
userId (integer, matches user.userId)
requestTime (datetime)
requestData (string, again split as needed)
然后您可以这样查询:

# Get a user
SELECT * FROM user WHERE userId = '123';
SELECT * FROM user WHERE userNAme = 'foo';

# Get all requests for a user
SELECT * FROM request WHERE userId = '123';
# Get a single request
SELECT * FROM request WHERE requestId = '325325';

# Get all notes for a user
SELECT * FROM note WHERE userId = '123';
# Get all notes from last week
SELECT * FROM note WHERE userId = '123' AND noteTime > CURDATE() - INTERVAL 1 WEEK;

# Add a note to user 123
INSERT INTO note (noteId, userId, noteData) VALUES (null, 123, 'This is a note');

请注意,使用规范化数据还可以做多少工作,以及它有多容易?查找、更新、附加或删除任何特定组件都很简单。

规范化的主要好处是消除冗余数据,但由于每个用户的数据对该用户都是唯一的,因此拆分此表并进行规范化没有任何好处。此外,由于前端无论如何都会将字典用作JSON对象,因此分解这些数据会导致不必要的复杂性和性能下降

好的,这是一个规范化的mySQL数据模型。注意:您可以将作者和标题分成两个表,以进一步减少数据冗余。您可能可以对“请求字典”使用类似的技术:


在您的情况下,我将抽象出处理此表的类。然后保持数据规范化。如果将来数据访问模式发生变化,我需要对数据进行规范化,我只需要在对程序影响较小的情况下这样做。我只需要更改处理这组数据的类来查询规范化的表,但返回的数据就像数据库结构从未更改一样。

您如何利用JSON数据?这是一款iPhone笔记应用程序。数据只是用户JSON格式的注释数组。重新
规范化并不能提高速度
——这当然需要限定。有时是真的,有时不是。正常化和速度。。。啊,古老的辩论。如果我有一个包含50个文本字段的表,可以将其规范化为几个表,那么如果我只查询类似的1个字段,那么规范化的速度肯定会更快。我的应用程序根本不需要在数据库中进行任何奇特的搜索或排序,它只需要检索特定电子邮件地址的JSON数据字符串,将其转换为数组,应用程序将知道如何处理它。在上表中,我有500000个用户,我想检索电子邮件的数据字段:steve@gmail.com. 我的数据是否规范化会影响此查询的性能吗?或者我目前的结构适合这种情况吗?当然可以正常化。对于关系数据库,如果您不知道是否要规范化,那么您肯定应该规范化。可以吗
# Get a user
SELECT * FROM user WHERE userId = '123';
SELECT * FROM user WHERE userNAme = 'foo';

# Get all requests for a user
SELECT * FROM request WHERE userId = '123';
# Get a single request
SELECT * FROM request WHERE requestId = '325325';

# Get all notes for a user
SELECT * FROM note WHERE userId = '123';
# Get all notes from last week
SELECT * FROM note WHERE userId = '123' AND noteTime > CURDATE() - INTERVAL 1 WEEK;

# Add a note to user 123
INSERT INTO note (noteId, userId, noteData) VALUES (null, 123, 'This is a note');
CREATE TABLE USERS(
  UID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  userName varchar(255) UNIQUE,
  password varchar(30),
  userEmail varchar(255) UNIQUE,
  deviceID varchar(255)
) ENGINE=InnoDB;

CREATE TABLE BOOKS(
  BKID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  FKUSERS int, 
  Title varchar(255),
  Author varchar(50)
) ENGINE=InnoDB;
ALTER TABLE BOOKS
  ADD FOREIGN KEY (FKUSERS)
    REFERENCES USERS(UID);

CREATE TABLE NOTES(
  ID int NOT NULL AUTO_INCREMENT PRIMARY KEY,
  FKUSERS int, 
  FKBOOKS int,
  Date date,
  Notes text
) ENGINE=InnoDB;

ALTER TABLE NOTES
  ADD FOREIGN KEY BKNO (FKUSERS)
    REFERENCES USERS(UID);
ALTER TABLE NOTES
  ADD FOREIGN KEY (FKBOOKS)
    REFERENCES BOOKS(BKID);