Sql 在数据库中保存动态列表的首选方法是什么?
在我们的应用程序中,用户可以创建不同的列表(如sharepoint),例如,用户可以创建汽车列表(名称、型号、品牌)和学生列表(姓名、出生日期、地址、国籍),e.t.c 我们的应用程序应该能够查询列表的不同列,所以我们不能只序列化每一行并将其保存在一行中 我应该在运行时为每个新创建的列表创建一个新表吗?如果这是最好的解决方案,那么我想Microsoft SharePoint可能也会这么做 我应该使用以下模式吗Sql 在数据库中保存动态列表的首选方法是什么?,sql,database,database-design,Sql,Database,Database Design,在我们的应用程序中,用户可以创建不同的列表(如sharepoint),例如,用户可以创建汽车列表(名称、型号、品牌)和学生列表(姓名、出生日期、地址、国籍),e.t.c 我们的应用程序应该能够查询列表的不同列,所以我们不能只序列化每一行并将其保存在一行中 我应该在运行时为每个新创建的列表创建一个新表吗?如果这是最好的解决方案,那么我想Microsoft SharePoint可能也会这么做 我应该使用以下模式吗 Lists (Id, Name) ListColumns (Id, ListId, N
Lists (Id, Name)
ListColumns (Id, ListId, Name)
ListRows (Id, ListId)
ListData(RowId, ColumnId, Value)
虽然一行在列表数据表中创建的行数与列表中的列数相同,但这感觉不太对
你处理过这种情况吗?您是如何在数据库中处理它的?也许一个潜在的解决方案是创建列表,可以包括为这些实体/列表创建
CREATE TABLE
语句
听起来数据库结构或模式可以在运行时更改,或者在用户的命令下更改,所以这样做可能会有所帮助吗
- 用户希望创建以前从未见过的实体的新列表。叫它电脑
- 用户定义属性(屏幕大小、CpuSpeed、AmountRAM、NumberOfCores)
- 系统允许用户在UI中创建
- 系统通常允许它们都是字符串,除非可以告诉我们何时所有提供的值都是日期或数字
- 构建创建脚本,针对数据库执行它们
- 将用户定义的数据插入到新表中
我认为您需要另一个名为ListRows的表,它告诉您哪些ListData记录属于同一行 听起来您的环境中可能已经部署了Sharepoint 考虑将您的应用程序与Sharepoint集成,并将其作为您的数据存储。当您可以利用Sharepoint时,无需重新创建您喜欢的所有Sharepoint内容 这需要进行一些配置,但您可以调用SP web服务来为您的列表数据进行CRUD
Sharepoint 2010还可以通过OData公开列表,这很容易从任何应用程序使用。用户创建列表时,绝对不应动态创建表。这不是数据库的工作方式 您的模式是正确的,在我看来,复数形式也是正确的,尽管我会删除驼峰大小写,并将它们称为
列表
,列表列
,列表行
和列表数据
我将通过跳过行
和列
表来进一步改进您的模式,它们没有任何作用。只需在每个单元格上附加一个行/列编号,并保持稀疏:不要在数据库中保留空单元格。您保留了基于行/列的查询/排序功能,您的查询将(可能会)更快,因为list\u单元格的数量将减少,并且您不必进行任何疯狂的连接来将数据链接回其表
以下是完整的模式:
create table lists (
id int primary key,
name varchar(25) not null
);
create table list_cells (
id int primary key,
list_id int not null references lists(id)
on delete cascade on update cascade,
row int not null,
col int not null,
data varchar(25) not null
);
我以前也经历过类似的情况-我不想分享实际的表模式,所以让我们使用一些建议的表结构进行一些思考练习:
- 让我们有一个
列表
表,其中包含所有我的列表
- 让我们也有一个
列
表,其中包含元数据(列名)
- 现在我们需要一个包含列值的
values
表
- 我们还需要一个包含所有行的列表的
rows
表,否则很难计算出实际有多少行
为了简单起见,让我们将所有内容都设置为字符串(VARCAHR
),并尝试提出一些查询:
统计表中的所有行
SELECT COUNT(*) FROM [rows]
JOIN [lists]
ON [rows].list_id = [Lists].id
WHERE [Lists].name = 'Cars'
BEGIN TRANSACTION
DECLARE @row_id INT
DECLARE @list_id INT
SELECT @list_id = id FROM [lists] WHERE name = 'Cars'
INSERT INTO [rows] (list_id) VALUES (@list_id)
SELECT @row_id = @@IDENTITY
DECLARE @column_id INT
-- === Need one of these for each column ===
SELECT @column_id = id FROM [columns]
WHERE name = 'Make'
AND list_id = @list_id
INSERT INTO [values] (column_id, row_id, value)
VALUES (@column_id, @row_id, 'Rover')
-- === Need one of these for each column ===
SELECT @column_id = id FROM [columns]
WHERE name = 'Model'
AND list_id = @list_id
INSERT INTO [values] (column_id, row_id, value)
VALUES (@column_id, @row_id, 'Metro')
COMMIT TRANSACTION
嗯,还不错,相比之下:
SELECT * FROM [Cars]
INSERT INTO [Cars] ([Make], [Model}) VALUES ('Rover', 'Metro')
将行插入表中
SELECT COUNT(*) FROM [rows]
JOIN [lists]
ON [rows].list_id = [Lists].id
WHERE [Lists].name = 'Cars'
BEGIN TRANSACTION
DECLARE @row_id INT
DECLARE @list_id INT
SELECT @list_id = id FROM [lists] WHERE name = 'Cars'
INSERT INTO [rows] (list_id) VALUES (@list_id)
SELECT @row_id = @@IDENTITY
DECLARE @column_id INT
-- === Need one of these for each column ===
SELECT @column_id = id FROM [columns]
WHERE name = 'Make'
AND list_id = @list_id
INSERT INTO [values] (column_id, row_id, value)
VALUES (@column_id, @row_id, 'Rover')
-- === Need one of these for each column ===
SELECT @column_id = id FROM [columns]
WHERE name = 'Model'
AND list_id = @list_id
INSERT INTO [values] (column_id, row_id, value)
VALUES (@column_id, @row_id, 'Metro')
COMMIT TRANSACTION
嗯,相比之下,开始有点毛茸茸的了:
SELECT * FROM [Cars]
INSERT INTO [Cars] ([Make], [Model}) VALUES ('Rover', 'Metro')
简单查询
我现在已经厌倦了构造繁琐复杂的SQL语句,因此您可以尝试对以下语句进行等效查询:
SELECT [Model] FROM [Cars] WHRE [Make] = 'Rover'
SELECT [Cars].[Make], [Cars].[Model], [Owners].[Name] FROM [Cars]
JOIN [Owners] ON [Owners].id = [Cars].owner_id
WHERE [Owners].Age > 50
SELECT [Cars].[Make], [Cars].[Model], [Owners].[Name] FROM [Cars]
JOIN [Owners] ON [Owners].id = [Cars].owner_id
JOIN [Addresses] ON [Addresses].id = [Owners].address_id
WHERE [Addresses].City = 'London'
我希望你开始明白了
简言之,我以前经历过这种情况,我可以向您保证,以这种方式在数据库中创建数据库肯定是件坏事
如果您需要对这些列表进行最基本的查询(我的字面意思是“我可以拥有此列表中的所有项目吗?”),您应该尝试寻找替代方法
只要每个用户都有自己的数据库,我肯定会推荐createtable
方法。即使他们不知道,我还是建议你至少考虑一下。