综合数据生成

使用随机生成器、算法、统计模型和大型语言模型 (LLM) 生成合成数据,以模拟实际数据,从而有效地开发和测试解决方案。

注意:

Oracle Database 19c(从版本 19.29 开始)和 Oracle AI Database 26ai(从版本 23.26 开始)都支持合成数据生成。

在开发和测试解决方案时,合成数据可能是一个强大的工具,特别是当实际数据尚不存在或不允许使用时。合成或人工生成的数据可以具有真实数据的许多特征。合成数据通常使用随机生成器、算法或统计模型创建,以模拟真实数据的特征和分布。然而,生产或依赖具有不同复杂功能的工具可能很复杂。随着大语言模型 (Large Language Models,LLM) 的可用性,可能会生成更多相关且特定于方案的数据,这些数据将考虑自然语言中表达的特征。

主题

合成数据的生成优势

综合数据生成支持填充数据库元数据克隆,支持开发、测试和机器学习项目,而无需使用原始表中的敏感数据。

合成数据生成具有以下优势:
  • 使用合成数据填充元数据克隆:元数据克隆复制数据库或方案的结构,而不包括实际数据。选择 AI 可以生成合成数据来填充这些克隆,从而在启用开发、测试和创建模板的同时保护敏感数据。此方法支持性能和可扩展性测试。

  • 启动新项目:启动新项目时,实际数据可能不可用。综合数据提供了逼真的示例,可帮助演示概念并获得项目提案支持。

  • 验证用户体验:综合数据通过提供各种数据集来发现设计缺陷、性能和可扩展性问题,有助于测试用户界面。

  • 支持 AI 和机器学习项目:当实际数据不可用或受限时,合成数据可用于训练 AI 和机器学习模型。LLM 可以生成具有特定模式的数据,以促进模型训练和评分。

生成合成数据

使用 DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA 函数生成合成数据并使用 Select AI 操作查询数据。

要了解详细信息,请参阅 GENERATE_SYNTHETIC_DATA 函数示例:生成合成数据

对合成数据生成进行监视和故障排除

当跨多个表生成大量数据时,Select AI 会将合成数据生成任务拆分为较小的块并并行运行任务。在 SYNTHETIC_DATA$<operation_id>_STATUS 表中跟踪每个块的状态。

合成数据生成操作记录在表 DBA_LOAD_OPERATIONSUSER_LOAD_OPERATIONS 中。使用这些表监视 DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA 操作。有关更多详细信息,请参见跟踪 DBMS_CLOUD Load Operations

在给定会话中运行合成数据生成后,可以使用以下方法从 USER_LOAD_OPERATION 获取最新的 <operation_id>
SELECT max(id) FROM user_load_operations;

要查看在其他会话中运行的合成数据操作,请使用 DBA_LOAD_OPERATIONS 视图。

查看合成数据的生成状态

合成数据生成操作的状态表显示每个表的进度及其相应的块。USER_LOAD_OPERATIONSDBA_LOAD_OPERATIONS 中的 STATUS_TABLE 列显示状态表名称。表名是 SYNTHETIC_DATA$<operation_id>_STATUS,它具有以下列:

名称 数据类型 说明

ID

NUMBER

记录的唯一标识符。

NAME

VARCHAR2

表的限定名称,例如 "ADB_USER"."EMPLOYEES"

BYTES

NUMBER

此数据生成任务的所需记录数量

ROWS_LOADED

NUMBER

生成的实际记录数。

CHECKSUM

VARCHAR2

此数据生成任务期间主键的起始值。

LAST_MODIFIED

TIMESTAMP WITH TIME ZONE

指示上次修改记录的时间戳。

STATUS

VARCHAR2

数据生成任务的状态。有效值是:
  • COMPLETED
  • FAILED
  • PENDING
  • SKIPPED

ERROR_CODE

NUMBER

错误代码,如果数据生成任务失败。

ERROR_MESSAGE

VARCHAR2

如果任务失败,则提供错误消息。

END_TIME

TIMESTAMP WITH TIME ZONE

标记数据生成任务结束的时间戳。
示例:检查为每个表生成的记录数

要检查为每个表生成的记录数,请发出以下命令:

SELECT name, SUM(rows_loaded) FROM synthetic_data$<operation_id>_status group by name;

查询 ROWS_LOADED 以确认为每个块加载的行数,查询 SUM(ROWS_LOADED) 以确认每个表的行数。

BEGIN
    DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
        profile_name => 'GENAI',
        object_list => '[{"owner": "ADB_USER", "name": "DIRECTOR","record_count":150},
                         {"owner": "ADB_USER", "name": "MOVIE_ACTOR","record_count":300},
                         {"owner": "ADB_USER", "name": "CLASSES", "user_prompt":"all in fall semester","record_count":5},
                         {"owner": "ADB_USER", "name": "ACTOR","record_count":220},
                         {"owner": "ADB_USER", "name": "MOVIE","record_count":50}]'
    );
END;
/
 
 
-- Check loaded rows for each chunk
SQL> SELECT name, rows_loaded FROM synthetic_data$141_status order by name;
NAME                           ROWS_LOADED
------------------------------------------
"ADB_USER"."ACTOR"                        188
"ADB_USER"."ACTOR"                         32
"ADB_USER"."CLASSES"                        5
"ADB_USER"."DIRECTOR"                     150
"ADB_USER"."MOVIE"                         50
"ADB_USER"."MOVIE_ACTOR"                   38
"ADB_USER"."MOVIE_ACTOR"                  114
"ADB_USER"."MOVIE_ACTOR"                  148
 
 
 
-- Check loaded rows for each table
SQL> SELECT name, SUM(rows_loaded) FROM synthetic_data$141_status group by name;
 
NAME                      SUM(ROWS_LOADED)
------------------------------------------
"ADB_USER"."DIRECTOR"                     150
"ADB_USER"."MOVIE_ACTOR"                  300
"ADB_USER"."CLASSES"                        5
"ADB_USER"."ACTOR"                        220
"ADB_USER"."MOVIE"                         50

示例:生成合成数据

本示例将探讨如何生成模拟真实数据的特征和分布的合成数据。

注意:

Oracle Database 19c(从版本 19.29 开始)和 Oracle Database 26ai(从版本 23.26 开始)都支持合成数据生成。

以下示例说明如何在方案中创建几个表,使用 OCI Generative AI 作为 AI 提供程序来创建 AI 配置文件,使用 DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA 函数将数据合成到这些表中,以及使用 Select AI 查询或生成对自然语言提示的响应。

--Create tables or use cloned tables

CREATE TABLE ADB_USER.Director (
    director_id     INT PRIMARY KEY,
    name            VARCHAR(100)
);
CREATE TABLE ADB_USER.Movie (
    movie_id        INT PRIMARY KEY,
    title           VARCHAR(100),
    release_date    DATE,
    genre           VARCHAR(50),
    director_id     INT,
    FOREIGN KEY (director_id) REFERENCES ADB_USER.Director(director_id)
);
CREATE TABLE ADB_USER.Actor (
    actor_id        INT PRIMARY KEY,
    name            VARCHAR(100)
);
CREATE TABLE ADB_USER.Movie_Actor (
    movie_id        INT,
    actor_id        INT,
    PRIMARY KEY (movie_id, actor_id),
    FOREIGN KEY (movie_id) REFERENCES ADB_USER.Movie(movie_id),
    FOREIGN KEY (actor_id) REFERENCES ADB_USER.Actor(actor_id)
);

-- Create the GenAI credential
BEGIN                                                                       
  DBMS_CLOUD.create_credential(                                             
    credential_name => 'GENAI_CRED',                                        
    user_ocid       => 'ocid1.user.oc1....',
    tenancy_ocid    => 'ocid1.tenancy.oc1....',
    private_key     => 'vZ6cO...',
    fingerprint     => '86:7d:...'    
  );                                                                        
END;                                                                       
/
 
-- Create a profile
BEGIN                                                                      
  DBMS_CLOUD_AI.CREATE_PROFILE(                                            
      profile_name =>'GENAI',                                                           
      attributes  =>'{"provider": "oci",                                                                 
        "credential_name": "GENAI_CRED",                                   
        "object_list": [{"owner": "ADB_USER", 
		"oci_compartment_id": "ocid1.compartment.oc1...."}]          
       }');                                                                
END;                                                                       
/
 
 
EXEC DBMS_CLOUD_AI.set_profile('GENAI');

-- Run the API for single table
BEGIN
    DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
        profile_name => 'GENAI',
        object_name  => 'Director',
        owner_name   => 'ADB_USER',
        record_count => 5
    );
END;
/
PL/SQL procedure successfully completed.
 
 
-- Query the table to see results
SQL> SELECT * FROM ADB_USER.Director;
 
DIRECTOR_ID NAME
----------- ----------------------------------------------------------------------------------------------------
          1 John Smith
          2 Emily Chen
          3 Michael Brown
          4 Sarah Taylor
          5 David Lee
 
 
-- Or ask select ai to show the results
SQL> select ai how many directors are there;
 
NUMBER_OF_DIRECTORS
-------------------
                  5
示例:为多个表生成合成数据

创建和设置 AI 提供程序配置文件后,使用 DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA 为多个表生成数据。您可以查询或使用 Select AI 来响应自然语言提示。

BEGIN
    DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
        profile_name => 'GENAI',
        object_list => '[{"owner": "ADB_USER", "name": "Director","record_count":5},
                         {"owner": "ADB_USER", "name": "Movie_Actor","record_count":5},
                         {"owner": "ADB_USER", "name": "Actor","record_count":10},
                         {"owner": "ADB_USER", "name": "Movie","record_count":5,"user_prompt":"all movies released in 2009"}]'
    );
END;
/
PL/SQL procedure successfully completed.
 
 
-- Query the table to see results
SQL> select * from ADB_USER.Movie;

 MOVIE_ID TITLE                                                     RELEASE_D                            GENRE                                 DIRECTOR_ID	
---------- -------------------------------------------------------- --------- --------------------------------------------------------------- -----------	
         1 The Dark Knight                                           15-JUL-09                              Action                              8	
         2 Inglourious Basterds                                      21-AUG-09                              War                                 3	
         3 Up in the Air                                             04-SEP-09                              Drama                               6	
         4 The Hangover                                              05-JUN-09                              Comedy                              1	
         5 District 9                                                14-AUG-09                              Science Fiction                     10	
	

 
-- Or ask select ai to show the results
SQL> select ai how many actors are there;
 
Number of Actors
----------------
              10
示例:使用示例行指导合成数据生成

要引导 AI 服务生成合成数据,您可以从表中随机选择现有记录。例如,通过将 {"sample_rows": 5} 添加到 params 参数,您可以将表中的 5 个样例行发送到 AI 提供程序。此示例根据 Transactions 表中的示例行生成另外 10 行。

BEGIN
  DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
    profile_name => 'GENAI',
    object_name  => 'Transactions',
    owner_name   => 'ADB_USER',
    record_count => 10,
    params       => '{"sample_rows":5}'
  );
END;
/
示例:使用用户提示定制合成数据生成

使用 user_prompt 参数可以指定数据生成的其他规则或要求。这可以应用于单个表,也可以作为多个表的 object_list 参数的一部分。例如,在对 DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA 的以下调用中,提示指示 AI 生成 2009 年发布的电影的合成数据。

-- Definition for the Movie table CREATE TABLE Movie 

CREATE TABLE Movie (
    movie_id        INT PRIMARY KEY,
    title           VARCHAR(100),
    release_date    DATE,
    genre           VARCHAR(50),
    director_id     INT,
    FOREIGN KEY (director_id) REFERENCES Director(director_id)
);
 
 
 
BEGIN
  DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
    profile_name      => 'GENAI',
    object_name       => 'Movie',
    owner_name        => 'ADB_USER',
    record_count      => 10,
    user_prompt       => 'all movies are released in 2009',
    params            => '{"sample_rows":5}'
  );
END;
/
 
BEGIN
    DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
        profile_name => 'GENAI',
        object_list => '[{"owner": "ADB_USER", "name": "Director","record_count":5},
                         {"owner": "ADB_USER", "name": "Movie_Actor","record_count":5},
                         {"owner": "ADB_USER", "name": "Actor","record_count":10},
                         {"owner": "ADB_USER", "name": "Movie","record_count":5,"user_prompt":"all movies are released in 2009"}]'
    );
END;
/
示例:使用表统计信息提高合成数据质量

如果表具有列统计信息,或者从包含元数据的数据库克隆表,则 Select AI 可以使用这些统计信息生成与原始数据非常相似或一致的数据。

对于 NUMBER 列,统计信息中的上限值和下限值将指导值范围。例如,如果原始 EMPLOYEES 表中的 SALARY 列范围从 1000 到 10000,则此列的合成数据也将在此范围内。

对于具有不同值的列,例如值为 CAWATXSTATE 列,合成数据将使用这些特定值。您可以使用 {"table_statistics": true/false} 参数管理此功能。默认情况下,将启用表统计信息。

BEGIN
  DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
    profile_name      => 'GENAI',
    object_name       => 'Movie',
    owner_name        => 'ADB_USER',
    record_count      => 10,
    user_prompt => 'all movies released in 2009',
    params            => '{"sample_rows":5,"table_statistics":true}'
  );
END;
/
示例:使用列注释指导数据生成

如果存在列注释,Select AI 会自动包括这些注释,以便在数据生成期间为 LLM 提供其他信息。例如,对“事务处理”表中的 Status 列的注释可能会列出允许的值,例如 successfulfailedpendingcanceledneed manual check。您还可以添加注释以进一步解释该列,从而为 AI 服务提供更精确的指令或提示来生成准确的数据。默认情况下,注释处于禁用状态。有关详细信息,请参阅可选参数

-- Use comment on column
COMMENT ON COLUMN Transaction.status IS 'the value for state should either be ''successful'', ''failed'', ''pending'' or ''canceled''';
/
 
BEGIN
    DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
        profile_name  => 'GENAI',
        object_name   => 'employees',
        owner_name    => 'ADB_USER',
        record_count  => 10
        params        => '{"comments":true}'
 
    );
END;
/
示例:在合成数据生成中设置唯一值

使用 LLM 生成大量合成数据时,可能会出现重复值。要防止出现这种情况,请在相关列上设置一个唯一约束条件。这可确保 Select AI 忽略 LLM 响应中具有重复值的行。此外,要限制某些列的值,可以使用 user_prompt 或添加注释来指定允许的值,例如将 STATE 列限制为 CAWATX

-- Use 'user_prompt'
BEGIN
    DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
        profile_name  => 'GENAI',
        object_name   => 'employees',
        owner_name    => 'ADB_USER',
        user_prompt   => 'the value for state should either be CA, WA, or TX',
        record_count  => 10
    );
END;
/
 
 
-- Use comment on column
COMMENT ON COLUMN EMPLOYEES.state IS 'the value for state should either be CA, WA, or TX'
/
示例:通过并行处理增强合成数据生成

为了减少运行时,Select AI 将合成数据生成任务拆分成较小的块,用于没有主键或数字主键的表。这些任务并行运行,与 AI 提供商交互以更高效地生成数据。数据库中的并行度 (Degree of Parallelism,DOP) 受 Autonomous AI Database on Dedicated Exadata Infrastructure 服务级别和 ECPU 或 OCPU 设置的影响,可确定每个块进程的记录数。并行运行任务通常可以提高性能,尤其是在跨多个表生成大量数据时。要管理合成数据生成的并行处理,请将 priority 设置为可选参数。请参阅可选参数

示例:启用或禁用数据访问

此示例说明管理员如何控制数据访问并阻止 Select AI 将实际方案表发送到 LLM。

禁用数据访问

要限制对方案表的访问,请以管理员身份登录并运行以下过程。

EXEC DBMS_CLOUD_AI.DISABLE_DATA_ACCESS;
 
PL/SQL procedure successfully completed.

禁用数据访问限制选择 AI 的 narrate 操作和合成数据生成。narrate 操作和合成数据生成会引发错误。

以数据库用户身份登录,创建并配置 AI 配置文件。查看 Use DBMS_CLOUD_AI to Configure AI Profiles 以配置 AI 配置文件。

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
          profile_name =>'DATA_ACCESS',
          attributes   =>'{"provider": "openai",
            "credential_name": "OPENAI_CRED",
            "object_list": [{"owner":"SH"}]
          }');
END;
/

EXEC DBMS_CLOUD_AI.SET_PROFILE('DATA_ACCESS');
 

select ai how many customers;

NUM_CUSTOMERS
55500

select ai narrate what are the top 3 customers in San Francisco;

ORA-20000: Data access is disabled for SELECT AI.
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD", line 2228
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD_AI", line 13157
ORA-06512: at line 1 https://docs.oracle.com/error-help/db/ora-20000/
The stored procedure 'raise_application_error' was called which causes this error to be generated
Error at Line: 1 Column: 6

以下示例显示了在尝试生成合成数据时触发的错误。

BEGIN
DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
profile_name => 'DATA_ACCESS_SDG',
object_name => 'CUSTOMERS_NEW',
owner_name => 'ADB_USER,
record_count => 5
);
END;
/ 

ERROR at line 1:

ORA-20000: Data access is disabled for SELECT AI.
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD", line 2228
ORA-06512: at "C##CLOUD$SERVICE.DBMS_CLOUD_AI", line 13401

ORA-06512: at line 2
启用数据访问

以下示例显示了如何启用数据访问。以管理员身份登录并运行以下过程:

EXEC DBMS_CLOUD_AI.ENABLE_DATA_ACCESS;
 
PL/SQL procedure successfully completed.

以数据库用户身份登录,创建并配置 AI 配置文件。查看 Use DBMS_CLOUD_AI to Configure AI Profiles 以配置 AI 配置文件。

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
          profile_name =>'DATA_ACCESS_NEW',
          attributes   =>'{"provider": "openai",
            "credential_name": "OPENAI_CRED",
            "object_list": [{"owner":"SH"}]
          }');
   END;
   /

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI.SET_PROFILE('DATA_ACCESS_NEW');

PL/SQL procedure successfully completed.


select ai how many customers;

NUM_CUSTOMERS
55500

select ai narrate what are the top 3 customers in San Francisco;

"RESPONSE"
"The top 3 customers in San Francisco are Cody Seto, Lauren Yaskovich, and Ian Mc"

以下示例显示了在启用数据访问后成功生成合成数据。

BEGIN
DBMS_CLOUD_AI.GENERATE_SYNTHETIC_DATA(
profile_name => 'DATA_ACCESS_SDG',
object_name => 'CUSTOMERS_NEW',
owner_name => 'ADB_USER',
record_count => 5
);
END;
/ 

PL/SQL procedure successfully completed.