在数据库级别处理动态数据字段出现了一个要求。假设我们有一个名为Employee的表,该表有一个名称,姓氏,并且没有联系字段(3个基本字段)。因此,随着应用程序的进展,要求数据库和应用程序应该能够添加(处理)可以随类型添加到数据库中的动态数据字段。
Ex:用户将动态地将出生数据,地址字段添加到Employee表中,该表主要有3个基本字段。
问题是如何以最佳方式满足这一要求?
我已经设计了一张桌子来满足此需求,但是我愿意采用行业标准的最佳方式来实现这一目标,而不会出现未来的问题
请与此协作。
答案 0 :(得分:1)
基本上,您可以使用四个选项来处理此类动态字段:
您在问题中没有提供足够的信息来确定哪一个最适合您的数据模型。
但是,这是优点和缺点的快速总结:
用于修改表:不利的一面是,修改表是一项昂贵的操作(尤其是当表变大时)。从正面看,所有用户都可以看到这些列,并且这些列具有适当的类型。
对于JSON:JSON非常灵活。但是,由于每次使用时都会重复每个字段的名称,因此JSON会产生非常大的存储开销。此外,您没有所有添加字段的列表(除非您将其保留在单独的表中)。
对于EAV:EAV是灵活的,但不如JSON灵活。问题在于value列是单个类型(通常是字符串),或者访问数据变得更加复杂。像JSON一样,每次使用时都会重复该值的“名称”。但是,这通常是另一个表的键,因此开销较小。
对于每个用户一个单独的表:这里的主要优点是将用户彼此隔离。如果这是必需的,那么这也许是可行的方法(尽管在EAV模型中添加userId
也可以)。
因此,最合适的方法取决于各种因素,例如:
答案 1 :(得分:0)
要具有动态字段,可以使用另一个表来设置用户属性
user
表中有列userid, name, surname, contact
user_props
表中有列propertyid, userid, property, value
在user_props
中,您可以插入用户属性,例如
INSERT INTO user_props. (userid, property, value)
VALUES (1, "date_of_birth", "2010-01-10"),(1, "hobby", "Stackoverflow")
像这样,您可以为用户动态设置任何数字属性。
答案 2 :(得分:0)
使用MongoDB或其他将NoData / Schemaless数据库存储在键=>值对中的数据库可能会更好。对于您事先确定的字段,可以设置类型(在MongoDB中),以便这些列具有模式。对于动态字段,这些字段将存储为字符串,并且您必须以某种方式找出代码中的类型。
如果您需要使用MySQL,则在Employee表中,您可以在自定义字段的第四列-数据库类型json。然后,无论何时添加新的自定义字段,都将添加field_name,field_value和field_type。您的架构可能类似于:
//Schema for Employee table in mysql
id: int
name: varchar
surname: varchar
custom_fields: json //eg { {field_name: DOB, field_value: 06/09/2020, field_type: date},... }
//Schema for contacts table
id: int
employee_id: int
contact: varchar
在MySQL中,您还可以摆脱custom_fields中的类型(如果可以不使用它的话),并将json构造为简单的key =>值对,这样看起来就像
{
{"key":"Age","value":"10"},
{"key":"salary","value":"40,000"},
{"key":"DOB","value":"06/09/2020"},
}
您似乎在设计here是Entity-Attribute-Value model的一种变体。它可以工作,但是针对这样的模式进行查询将非常麻烦。使用json列更整洁,也更快。最好是使用MongoDB并找出代码中的类型。
答案 3 :(得分:0)
您可以使用包含ALTER DATABASE语句的存储过程来处理这种情况。像这样:
DROP PROCEDURE IF EXISTS set_dynamic_table;
DELIMITER //
CREATE PROCEDURE set_dynamic_table (IN _field_name VARCHAR(50),
IN _field_type VARCHAR(20),
IN _last_field_name varchar(50))
BEGIN
DECLARE _stmt VARCHAR(1024);
SET @SQL := CONCAT('ALTER TABLE dynamic_table',
'ADD COLUMN ' _field_name, field_type, NULL AFTER ,last_field_name);
PREPARE _stmt FROM @SQL;
EXECUTE _stmt;
DEALLOCATE PREPARE _stmt;
END//
DELIMITER;
然后你会