You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对以下SQL临时表进行数据库规范化处理?

数据库规范化处理方案

针对给定的临时表#A和#B,需按照数据库范式(核心满足第一范式1NF,同时延伸至2NF、3NF)拆分结构,最终形成3个符合规范的独立表:用户表、产品表、用户-产品关联表。

问题核心分析

  • #A表:当前数据无重复,但存在冗余风险(若同一用户多次出现会重复存储信息),可作为用户基础数据的核心来源。
  • #B表:NAME字段为逗号分隔的多值内容,违反第一范式(要求列值具备原子性,不可拆分),这是需要解决的核心问题,必须拆分多值字段并建立多对多关联关系。

规范化后表结构

1. 用户表(Users)

存储唯一用户信息,确保每个用户仅存储一次:

CREATE TABLE Users (
    UserID VARCHAR(5) PRIMARY KEY, -- 复用#A中的ID作为主键,新增用户需生成唯一标识
    UserName VARCHAR(10) NOT NULL UNIQUE,
    Number INT NULL -- #B中新增用户无该字段值,允许为空
);

2. 产品表(Products)

存储唯一产品信息:

CREATE TABLE Products (
    ProductID INT IDENTITY(1,1) PRIMARY KEY, -- 自增主键,也可直接用产品名作为主键
    ProductName VARCHAR(10) NOT NULL UNIQUE
);

3. 用户-产品关联表(UserProductRelations)

存储用户与产品的多对多关联关系,通过外键绑定两个主表:

CREATE TABLE UserProductRelations (
    RelationID INT IDENTITY(1,1) PRIMARY KEY,
    UserID VARCHAR(5) NOT NULL FOREIGN KEY REFERENCES Users(UserID),
    ProductID INT NOT NULL FOREIGN KEY REFERENCES Products(ProductID),
    UNIQUE(UserID, ProductID) -- 避免同一用户与产品的重复关联
);

数据迁移步骤

1. 导入#A的用户数据到Users表

INSERT INTO Users(UserID, UserName, Number)
SELECT ID, NAME, NUMBER FROM #A;

2. 处理#B中的新增用户(HARRY、KATTY、ALEX)

先拆分#B的多值NAME字段,提取所有唯一用户后插入Users表(示例中为新增用户生成自定义ID,也可改用自增ID):

-- 拆分#B的多值NAME字段
WITH SplitUsers AS (
    SELECT 
        TRIM(value) AS UserName
    FROM #B
    CROSS APPLY STRING_SPLIT(NAME, ',')
)
-- 插入未在Users表中的新用户
INSERT INTO Users(UserName, UserID, Number)
SELECT 
    UserName,
    LEFT(UPPER(UserName), 1) + CAST(ROW_NUMBER() OVER(ORDER BY UserName) AS VARCHAR(4)) AS UserID, -- 示例:HARRY→H1
    NULL AS Number
FROM SplitUsers
WHERE UserName NOT IN (SELECT UserName FROM Users);

3. 导入产品数据到Products表

INSERT INTO Products(ProductName)
SELECT DISTINCT PRODUCT FROM #B;

4. 拆分#B数据并导入关联表

WITH SplitProductUsers AS (
    SELECT 
        b.PRODUCT,
        TRIM(s.value) AS UserName
    FROM #B b
    CROSS APPLY STRING_SPLIT(b.NAME, ',') s
)
INSERT INTO UserProductRelations(UserID, ProductID)
SELECT 
    u.UserID,
    p.ProductID
FROM SplitProductUsers spu
JOIN Users u ON spu.UserName = u.UserName
JOIN Products p ON spu.PRODUCT = p.ProductName;

验证查询

通过关联查询验证数据正确性,例如查询每个产品对应的用户:

SELECT 
    p.ProductName,
    STRING_AGG(u.UserName, ', ') AS Users
FROM Products p
JOIN UserProductRelations upr ON p.ProductID = upr.ProductID
JOIN Users u ON upr.UserID = u.UserID
GROUP BY p.ProductName;

内容的提问来源于stack exchange,提问作者keshar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 03:01:09