多主键
更新时间:2024-05-22
什么是多主键
在数据库设计中,多主键通常被称为联合主键或复合主键。它指的是使用多个字段的组合作为主键,以唯一地标识表中的每一行数据。在某些特定的业务场景中,如具有复杂唯一性约束的数据模型或需要多个属性来唯一标识一个实体的场景,多主键是非常有用的。
VectorDB允许客户在建表时设置多主键,主键字段之间的先后顺序由表Schema定义时的顺序决定。
多主键的使用限制
多主键在使用上存在一些限制,说明如下:
- 主键最多可以支持10个字段。
- 分区键仍然只支持1个字段:分区键可以是主键的某个字段,也可以是非主键字段,若用户没有指定分区键,则默认将第一个主键字段认做分区键。
- 索引键仍然不可以是主键的任何字段。
使用示例
我们通过Python SDK展示一下多主键的使用。
- 创建一个莫愁客户端对象。
import time
import json
import random
import pymochow
import logging
from pymochow.configuration import Configuration
from pymochow.auth.bce_credentials import BceCredentials
from pymochow.exception import ClientError, ServerError
from pymochow.model.schema import Schema, Field, SecondaryIndex, VectorIndex, HNSWParams
from pymochow.model.enum import FieldType, IndexType, MetricType, ServerErrCode
from pymochow.model.enum import TableState, IndexState
from pymochow.model.table import Partition, Row, AnnSearch, HNSWSearchParams
logging.basicConfig(filename='documentinsight.log', level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
if __name__ == "__main__":
account = '$您的账户名称'
api_key = '$您的账户API密钥'
endpoint = '$您的实例访问端点' # 例如:'http://127.0.0.1:5287'
db_name = 'DocumentInsight'
table_name = 'AutoIncrementTestTable'
# 根据配置创建一个MochowClient对象
config = Configuration(credentials=BceCredentials(account, api_key), endpoint=endpoint)
mochow_client = pymochow.MochowClient(config)
- 创建一个带多主键的表,该表主键包含两个字段,分别是DocId字段,类型为UINT64;UserId字段,类型为STRING。
# 建库
db = mochow_client.create_database(db_name);
# 若库已存在,则直接使用下述代码获取一个库对象
# db = mochow_client.database(db_name)
# 建表,该表有2个分区
fields = []
fields.append(Field("DocId", FieldType.UINT64, primary_key=True, partition_key=True, auto_increment=False, not_null=True))
fields.append(Field("UserId", FieldType.STRING, primary_key=True, partition_key=False, auto_increment=False, not_null=True))
fields.append(Field("DocTitle", FieldType.STRING))
table = db.create_table(
table_name=table_name,
replication=1,
partition=Partition(partition_num=2), # 2个分区
schema=Schema(fields=fields, indexes=[])
)
while True:
time.sleep(1)
table = db.describe_table(table_name)
if table.state == TableState.NORMAL:
break
- 插入几条数据。
# 插入几条数据
rows = [
Row(DocId=1, UserId='user-1', DocTitle='To Kill a Mockingbird'),
Row(DocId=2, UserId='user-1', DocTitle='The Great Gatsby'),
Row(DocId=1, UserId='user-2', DocTitle='To Kill a Mockingbird'),
Row(DocId=2, UserId='user-2', DocTitle='The Great Gatsby'),
]
table.upsert(rows=rows)
- 我们执行标量查询,输入待查询目标记录的主键值,代码如下:
# 标量查询,查询主键中DocId字段为1、UserId字段为'user-1'的完整数据
primary_key = {'DocId':1, 'UserId':'user-1'}
results = table.query(primary_key=primaryKey)
print("Query result: {}".format(results))
执行完上述代码之后,我们会从控制台中观察到1行输出,如下所示:
Query result: {metadata:{content__length:u'97',content__type:u'application/json',request_id:u'14ccd3b6-fde3-400e-b81c-6930e31726ef'},row:{'DocId': 1, 'UserId': 'user-1', 'DocTitle': 'To Kill a Mockingbird'},code:0,msg:u'Success'}
我们可以看到该行的完整数据的值与写入时的值完全一致,符合预期。