📖 数据密集型设计

数据标准管理与数据字典

深入探讨数据标准制定、数据字典建设及数据规范化管理

一、数据标准概述

数据标准是数据治理的基础,定义了数据的统一规范和规则。数据字典是数据标准的具体体现,记录了数据的定义、属性和关系。通过数据标准管理和数据字典建设,能够实现数据的规范化和一致性。

二、数据标准体系

2.1 数据标准分类

类型 描述 示例 作用
术语标准 业务术语定义 订单、用户、产品 统一理解
数据元标准 数据元素定义 字段名称、类型、长度 数据一致性
编码标准 编码规则定义 订单号、用户ID 唯一标识
格式标准 数据格式规范 日期、时间、金额 格式统一
分类标准 数据分类规则 行业分类、产品类别 规范分类

2.2 数据标准管理架构

graph TD A[数据标准制定] --> B[标准评审] B --> C[标准发布] C --> D[标准实施] D --> D1[数据建模] D --> D2[数据开发] D --> D3[数据集成] D --> D4[数据质量] D --> E[标准监控] E --> F[标准变更] F --> B

三、数据标准管理

3.1 数据标准定义

public class DataStandardService
{
    public async Task CreateStandardAsync(DataStandardDto dto)
    {
        var standard = new DataStandard
        {
            Id = Guid.NewGuid().ToString(),
            Name = dto.Name,
            Code = dto.Code,
            Description = dto.Description,
            Category = dto.Category,
            Status = StandardStatus.Draft,
            Version = "1.0",
            CreatedBy = dto.CreatedBy,
            CreatedAt = DateTime.UtcNow
        };
        
        await _standardRepository.SaveStandardAsync(standard);
        
        return standard;
    }
    
    public async Task ReviewStandardAsync(string standardId, ReviewDto dto)
    {
        var standard = await _standardRepository.GetStandardAsync(standardId);
        
        if (standard == null)
        {
            throw new NotFoundException("数据标准不存在");
        }
        
        standard.Status = dto.Approved ? StandardStatus.Approved : StandardStatus.Rejected;
        standard.ReviewedBy = dto.ReviewedBy;
        standard.ReviewedAt = DateTime.UtcNow;
        standard.ReviewComment = dto.Comment;
        
        await _standardRepository.SaveStandardAsync(standard);
        
        return standard;
    }
    
    public async Task PublishStandardAsync(string standardId)
    {
        var standard = await _standardRepository.GetStandardAsync(standardId);
        
        if (standard == null)
        {
            throw new NotFoundException("数据标准不存在");
        }
        
        if (standard.Status != StandardStatus.Approved)
        {
            throw new ValidationException("数据标准未批准");
        }
        
        standard.Status = StandardStatus.Published;
        standard.PublishedAt = DateTime.UtcNow;
        
        await _standardRepository.SaveStandardAsync(standard);
        
        return standard;
    }
    
    public async Task> GetStandardsByCategoryAsync(string category)
    {
        return await _standardRepository.GetStandardsByCategoryAsync(category);
    }
    
    public async Task> GetAllStandardsAsync(StandardStatus? status = null)
    {
        return await _standardRepository.GetAllStandardsAsync(status);
    }
}

public class DataStandard
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public string Description { get; set; }
    public string Category { get; set; }
    public StandardStatus Status { get; set; }
    public string Version { get; set; }
    public string CreatedBy { get; set; }
    public DateTime CreatedAt { get; set; }
    public string ReviewedBy { get; set; }
    public DateTime? ReviewedAt { get; set; }
    public string ReviewComment { get; set; }
    public DateTime? PublishedAt { get; set; }
}

public enum StandardStatus { Draft, PendingReview, Approved, Rejected, Published, Deprecated }

3.2 数据元标准管理

public class DataElementService
{
    public async Task CreateDataElementAsync(DataElementDto dto)
    {
        var element = new DataElement
        {
            Id = Guid.NewGuid().ToString(),
            Name = dto.Name,
            Code = dto.Code,
            DataType = dto.DataType,
            Length = dto.Length,
            Precision = dto.Precision,
            Scale = dto.Scale,
            IsNullable = dto.IsNullable,
            BusinessDefinition = dto.BusinessDefinition,
            TechnicalDefinition = dto.TechnicalDefinition,
            Domain = dto.Domain,
            Status = ElementStatus.Draft
        };
        
        await _elementRepository.SaveDataElementAsync(element);
        
        return element;
    }
    
    public async Task ValidateDataElementAsync(DataElement element)
    {
        var issues = new List();
        
        if (string.IsNullOrEmpty(element.Code))
        {
            issues.Add(new ValidationIssue { Field = "Code", Message = "数据元编码不能为空" });
        }
        
        if (element.DataType == "DECIMAL" && (element.Precision == null || element.Scale == null))
        {
            issues.Add(new ValidationIssue { Field = "Precision/Scale", Message = "DECIMAL类型需要指定精度和小数位" });
        }
        
        if (element.DataType == "VARCHAR" && element.Length == null)
        {
            issues.Add(new ValidationIssue { Field = "Length", Message = "VARCHAR类型需要指定长度" });
        }
        
        if (issues.Count > 0)
        {
            throw new ValidationException("数据元验证失败", issues);
        }
        
        element.ValidationStatus = ValidationStatus.Passed;
        
        return element;
    }
    
    public async Task> GetDataElementsByDomainAsync(string domain)
    {
        return await _elementRepository.GetDataElementsByDomainAsync(domain);
    }
    
    public async Task> SearchDataElementsAsync(string keyword)
    {
        return await _elementRepository.SearchDataElementsAsync(keyword);
    }
}

public class DataElement
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Code { get; set; }
    public string DataType { get; set; }
    public int? Length { get; set; }
    public int? Precision { get; set; }
    public int? Scale { get; set; }
    public bool IsNullable { get; set; }
    public string BusinessDefinition { get; set; }
    public string TechnicalDefinition { get; set; }
    public string Domain { get; set; }
    public ElementStatus Status { get; set; }
    public ValidationStatus ValidationStatus { get; set; }
}

public enum ElementStatus { Draft, Reviewed, Approved, Published, Deprecated }
public enum ValidationStatus { Pending, Passed, Failed }

四、数据字典

4.1 数据字典设计

graph TD A[数据字典] --> B[数据库字典] A --> C[业务字典] A --> D[指标字典] A --> E[代码字典] B --> B1[表结构] B --> B2[字段定义] B --> B3[索引信息] C --> C1[业务术语] C --> C2[业务规则] C --> C3[业务流程] D --> D1[指标定义] D --> D2[计算逻辑] D --> D3[数据来源] E --> E1[编码规则] E --> E2[代码值] E --> E3[代码映射]

4.2 数据字典实现

public class DataDictionaryService
{
    public async Task GetEntryAsync(string databaseName, string tableName, string columnName)
    {
        return await _dictionaryRepository.GetEntryAsync(databaseName, tableName, columnName);
    }
    
    public async Task> GetTableEntriesAsync(string databaseName, string tableName)
    {
        return await _dictionaryRepository.GetEntriesAsync(databaseName, tableName);
    }
    
    public async Task> GetDatabaseEntriesAsync(string databaseName)
    {
        return await _dictionaryRepository.GetEntriesAsync(databaseName);
    }
    
    public async Task UpdateEntryAsync(DictionaryEntry entry)
    {
        var existingEntry = await _dictionaryRepository.GetEntryAsync(
            entry.DatabaseName, entry.TableName, entry.ColumnName);
        
        if (existingEntry == null)
        {
            throw new NotFoundException("字典条目不存在");
        }
        
        existingEntry.BusinessDefinition = entry.BusinessDefinition;
        existingEntry.Owner = entry.Owner;
        existingEntry.DataClassification = entry.DataClassification;
        existingEntry.SensitiveLevel = entry.SensitiveLevel;
        existingEntry.UpdatedAt = DateTime.UtcNow;
        
        await _dictionaryRepository.SaveEntryAsync(existingEntry);
        
        return existingEntry;
    }
    
    public async Task CreateEntryAsync(DictionaryEntry entry)
    {
        entry.Id = Guid.NewGuid().ToString();
        entry.CreatedAt = DateTime.UtcNow;
        entry.UpdatedAt = DateTime.UtcNow;
        
        await _dictionaryRepository.SaveEntryAsync(entry);
        
        return entry;
    }
    
    public async Task> SearchEntriesAsync(string keyword)
    {
        return await _dictionaryRepository.SearchEntriesAsync(keyword);
    }
    
    public async Task GenerateReportAsync(string databaseName)
    {
        var entries = await GetDatabaseEntriesAsync(databaseName);
        
        return new DictionaryReport
        {
            DatabaseName = databaseName,
            GeneratedAt = DateTime.UtcNow,
            TotalTables = entries.Select(e => e.TableName).Distinct().Count(),
            TotalColumns = entries.Count,
            SensitiveColumns = entries.Count(e => e.SensitiveLevel >= SensitiveLevel.High),
            Entries = entries
        };
    }
}

public class DictionaryEntry
{
    public string Id { get; set; }
    public string DatabaseName { get; set; }
    public string TableName { get; set; }
    public string ColumnName { get; set; }
    public string DataType { get; set; }
    public int? Length { get; set; }
    public bool IsNullable { get; set; }
    public string BusinessDefinition { get; set; }
    public string TechnicalDefinition { get; set; }
    public string Owner { get; set; }
    public string DataClassification { get; set; }
    public SensitiveLevel SensitiveLevel { get; set; }
    public DateTime CreatedAt { get; set; }
    public DateTime UpdatedAt { get; set; }
}

public enum SensitiveLevel { None, Low, Medium, High, Critical }

五、数据编码标准

5.1 编码规则设计

public class CodeStandardService
{
    public async Task CreateCodeStandardAsync(CodeStandardDto dto)
    {
        var standard = new CodeStandard
        {
            Id = Guid.NewGuid().ToString(),
            CodeType = dto.CodeType,
            CodePattern = dto.CodePattern,
            Description = dto.Description,
            Validator = dto.Validator,
            Status = StandardStatus.Draft
        };
        
        await _codeRepository.SaveCodeStandardAsync(standard);
        
        return standard;
    }
    
    public bool ValidateCode(string code, CodeStandard standard)
    {
        if (standard.Validator == "REGEX")
        {
            return Regex.IsMatch(code, standard.CodePattern);
        }
        
        if (standard.Validator == "LENGTH")
        {
            var length = int.Parse(standard.CodePattern);
            return code.Length == length;
        }
        
        if (standard.Validator == "FORMAT")
        {
            return ValidateFormat(code, standard.CodePattern);
        }
        
        return true;
    }
    
    private bool ValidateFormat(string code, string pattern)
    {
        var parts = pattern.Split('-');
        var codeParts = code.Split('-');
        
        if (parts.Length != codeParts.Length)
        {
            return false;
        }
        
        for (int i = 0; i < parts.Length; i++)
        {
            var partPattern = parts[i];
            
            if (partPattern.StartsWith('N'))
            {
                var length = int.Parse(partPattern.Substring(1));
                if (!Regex.IsMatch(codeParts[i], $"^\\d{{{length}}}$"))
                {
                    return false;
                }
            }
            else if (partPattern.StartsWith('A'))
            {
                var length = int.Parse(partPattern.Substring(1));
                if (!Regex.IsMatch(codeParts[i], $"^[A-Za-z]{{{length}}}$"))
                {
                    return false;
                }
            }
        }
        
        return true;
    }
    
    public string GenerateCode(CodeStandard standard)
    {
        if (standard.CodePattern == "UUID")
        {
            return Guid.NewGuid().ToString();
        }
        
        if (standard.CodePattern == "SNOWFLAKE")
        {
            return _snowflakeGenerator.Generate().ToString();
        }
        
        if (standard.CodePattern.StartsWith("DATE"))
        {
            var format = standard.CodePattern.Replace("DATE", "");
            return DateTime.Now.ToString(format);
        }
        
        return string.Empty;
    }
    
    public async Task> GetCodeValuesAsync(string codeType)
    {
        return await _codeRepository.GetCodeValuesAsync(codeType);
    }
    
    public async Task GetCodeValueAsync(string codeType, string code)
    {
        return await _codeRepository.GetCodeValueAsync(codeType, code);
    }
}

public class CodeStandard
{
    public string Id { get; set; }
    public string CodeType { get; set; }
    public string CodePattern { get; set; }
    public string Description { get; set; }
    public string Validator { get; set; }
    public StandardStatus Status { get; set; }
}

public class CodeValue
{
    public string CodeType { get; set; }
    public string Code { get; set; }
    public string Value { get; set; }
    public string Description { get; set; }
    public int SortOrder { get; set; }
    public bool IsActive { get; set; }
}

六、数据标准监控与审计

6.1 数据标准监控

public class StandardComplianceMonitor
{
    public async Task CheckComplianceAsync(string databaseName)
    {
        var report = new ComplianceReport
        {
            DatabaseName = databaseName,
            CheckTime = DateTime.UtcNow,
            Issues = new List()
        };
        
        var tables = await _metadataService.GetTablesAsync(databaseName);
        
        foreach (var table in tables)
        {
            foreach (var column in table.Columns)
            {
                var standard = await _dataElementService.GetDataElementAsync(column.ColumnName);
                
                if (standard != null)
                {
                    if (column.DataType != standard.DataType)
                    {
                        report.Issues.Add(new ComplianceIssue
                        {
                            TableName = table.TableName,
                            ColumnName = column.ColumnName,
                            IssueType = IssueType.DataTypeMismatch,
                            Expected = standard.DataType,
                            Actual = column.DataType,
                            Severity = Severity.High
                        });
                    }
                    
                    if (column.IsNullable != standard.IsNullable)
                    {
                        report.Issues.Add(new ComplianceIssue
                        {
                            TableName = table.TableName,
                            ColumnName = column.ColumnName,
                            IssueType = IssueType.NullableMismatch,
                            Expected = standard.IsNullable.ToString(),
                            Actual = column.IsNullable.ToString(),
                            Severity = Severity.Medium
                        });
                    }
                }
            }
        }
        
        report.ComplianceRate = tables.Count > 0 ? 
            (double)(tables.Count * 10 - report.Issues.Count) / (tables.Count * 10) : 1.0;
        
        return report;
    }
    
    public async Task> CheckAllDatabasesComplianceAsync()
    {
        var reports = new List();
        
        var databases = await _metadataService.GetAllDatabaseNamesAsync();
        
        foreach (var database in databases)
        {
            var report = await CheckComplianceAsync(database);
            reports.Add(report);
        }
        
        return reports;
    }
    
    public async Task> GetCriticalIssuesAsync()
    {
        var allReports = await CheckAllDatabasesComplianceAsync();
        
        return allReports
            .SelectMany(r => r.Issues)
            .Where(i => i.Severity == Severity.Critical || i.Severity == Severity.High)
            .OrderByDescending(i => i.Severity)
            .ToList();
    }
}

public class ComplianceReport
{
    public string DatabaseName { get; set; }
    public DateTime CheckTime { get; set; }
    public List Issues { get; set; } = new();
    public double ComplianceRate { get; set; }
}

public class ComplianceIssue
{
    public string TableName { get; set; }
    public string ColumnName { get; set; }
    public IssueType IssueType { get; set; }
    public string Expected { get; set; }
    public string Actual { get; set; }
    public Severity Severity { get; set; }
}

6.2 数据标准审计

public class StandardAuditService
{
    public async Task LogChangeAsync(AuditAction action, string targetType, string targetId, string details)
    {
        var log = new AuditLog
        {
            Id = Guid.NewGuid().ToString(),
            Action = action,
            TargetType = targetType,
            TargetId = targetId,
            Details = details,
            Operator = _currentUserService.GetCurrentUserId(),
            OperatedAt = DateTime.UtcNow
        };
        
        await _auditRepository.SaveAuditLogAsync(log);
        
        return log;
    }
    
    public async Task> GetAuditLogsAsync(AuditQuery query)
    {
        return await _auditRepository.GetAuditLogsAsync(query);
    }
    
    public async Task> GetLogsByTargetAsync(string targetType, string targetId)
    {
        return await _auditRepository.GetLogsByTargetAsync(targetType, targetId);
    }
    
    public async Task GenerateAuditSummaryAsync(DateTime startTime, DateTime endTime)
    {
        var logs = await _auditRepository.GetAuditLogsByTimeRangeAsync(startTime, endTime);
        
        return new AuditSummary
        {
            StartTime = startTime,
            EndTime = endTime,
            TotalChanges = logs.Count,
            CreationCount = logs.Count(l => l.Action == AuditAction.Create),
            UpdateCount = logs.Count(l => l.Action == AuditAction.Update),
            DeleteCount = logs.Count(l => l.Action == AuditAction.Delete),
            Operators = logs.Select(l => l.Operator).Distinct().Count()
        };
    }
}

public class AuditLog
{
    public string Id { get; set; }
    public AuditAction Action { get; set; }
    public string TargetType { get; set; }
    public string TargetId { get; set; }
    public string Details { get; set; }
    public string Operator { get; set; }
    public DateTime OperatedAt { get; set; }
}

public enum AuditAction { Create, Update, Delete, Review, Publish, Deprecate }

七、数据标准最佳实践

7.1 数据标准实施策略

策略 描述 实现方式
顶层设计 统一规划数据标准 标准委员会
分步实施 分阶段推进 优先级排序
持续优化 定期更新标准 版本管理
强制遵守 确保标准执行 自动化校验
培训推广 提高意识 培训文档

7.2 数据字典建设建议

  • 建立完整的数据字典体系
  • 实现数据字典自动化维护
  • 建立数据字典版本管理
  • 提供数据字典查询接口
  • 定期审核数据字典内容

八、总结

数据标准管理与数据字典是数据治理的基础。通过制定数据标准、建设数据字典,能够实现数据的规范化和一致性。数据标准监控和审计能够确保标准的执行,及时发现合规问题。建设完善的数据标准体系,能够提升数据质量,支持数据驱动的决策。