【鸿蒙】数据管理--关系型数据库
关系型数据库概述
关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库。HarmonyOS关系型数据库基于SQLite组件提供了一套完整的对本地数据库进行管理的机制,对外提供了一系列的增、删、改、查等接口,也可以直接运行用户输入的SQL语句来满足复杂的场景需要。HarmonyOS提供的关系型数据库功能更加完善,查询效率更加高效。
基本概念
- 关系型数据库
基于关系模型来管理数据的数据库,以行和列的形式存储数据。
- 谓词
数据库中用来代表数据实体的性质、特征或者数据实体之间关系的词项,主要用来定义数据库的操作条件。
- 结果集
指用户查询之后的结果集合,可以对数据进行访问。结果集提供了灵活的数据访问方式,可以更方便的拿到用户想要的数据。
- SQLite数据库
一款轻型的数据库,是遵守ACID的关系型数据库管理系统。它是一个开源的项目。
运作机制
HarmonyOS关系型数据库对外提供通用的操作接口,底层使用SQLite作为持久化存储引擎,支持SQLite具有的所有数据库特性,包括但不限于事务、索引、视图、触发器、外键、参数化查询和预编译SQL语句。
图1 关系型数据库运作机制
默认配置
- 如果不指定数据库的日志模式,那么系统默认日志方式是WAL(Write Ahead Log)模式。
- 如果不指定数据库的落盘模式,那么系统默认落盘方式是FULL模式。
- HarmonyOS数据库使用的共享内存默认大小是2MB。
约束与限制
- 数据库中连接池的最大数量是4个,用以管理用户的读写操作。
- 为保证数据的准确性,数据库同一时间只能支持一个写操作。
场景介绍
关系型数据库是在SQLite基础上实现的本地数据操作机制,提供给用户无需编写原生SQL语句就能进行数据增删改查的方法,同时也支持原生SQL语句操作。
接口说明
数据库的创建和删除
关系型数据库提供了数据库创建方式,以及对应的删除接口,涉及的API如下所示。
类名 |
接口名 |
描述 |
---|---|---|
DatabaseHelper |
DatabaseHelper(Context context) |
DatabaseHelper是数据库操作的辅助类,当数据库创建成功后,数据库文件将存储在由上下文指定的目录里。数据库文件存储的路径会因指定不同的上下文存在差异。
|
StoreConfig.Builder |
public StoreConfig builder() |
对数据库进行配置,包括设置数据库名、存储模式、日志模式、同步模式,是否为只读,及数据库加密。 |
RdbOpenCallback |
public abstract void onCreate(RdbStore store) |
数据库创建时被回调,开发者可以在该方法中初始化表结构,并添加一些应用使用到的初始化数据。 |
RdbOpenCallback |
public abstract void onUpgrade(RdbStore store, int currentVersion, int targetVersion) |
数据库升级时被回调。 |
RdbOpenCallback |
public void onDowngrade(RdbStore store, int currentVersion, int targetVersion) |
数据库降级时被回调。 |
DatabaseHelper |
public RdbStore getRdbStore(StoreConfig config, int version, RdbOpenCallback openCallback, ResultSetHook resultSetHook) |
根据配置创建或打开数据库。 |
DatabaseHelper |
public boolean deleteRdbStore(String name) |
删除指定的数据库。 |
数据库的加密
关系型数据库提供数据库加密的能力,在创建数据库时若指定了密钥,则会创建为加密数据库再次使用此数据库时,仍需要指定相同密钥,才能正确打开数据库。
类名 |
接口名 |
描述 |
---|---|---|
StoreConfig.Builder |
public StoreConfig.Builder setEncryptKey(byte[] encryptKey) |
为数据库设置数据库加密密钥的配置类,创建或打开数据库时传入包含数据库加密密钥的配置类,即可创建或打开加密数据库。 |
数据库的增删改查
关系型数据库提供对本地数据增删改查操作的能力,相关API如下所示。
- 新增关系型数据库提供了插入数据的接口,通过ValuesBucket输入要存储的数据,通过返回值判断是否插入成功,插入成功时返回最新插入数据所在的行号,失败时则返回-1。
表3 数据库插入API
类名
接口名
描述
RdbStore
long insert(String table, ValuesBucket initialValues)
向数据库插入数据。
- table:待添加数据的表名。
- initialValues:以ValuesBucket存储的待插入的数据。它提供一系列put方法,如putString(String columnName, String values),putDouble(String columnName, double value),用于向ValuesBucket中添加数据。
- 更新
调用更新接口,传入要更新的数据,并通过AbsRdbPredicates指定更新条件。该接口的返回值表示更新操作影响的行数。如果更新失败,则返回0。
表4 数据库更新API
类名
接口名
描述
RdbStore
int update(ValuesBucket values, AbsRdbPredicates predicates)
更新数据库表中符合谓词指定条件的数据。
- values:以ValuesBucket存储的要更新的数据。
- predicates:指定了更新操作的表名和条件。AbsRdbPredicates的实现类有两个:RdbPredicates和RawRdbPredicates。
- RdbPredicates:支持调用谓词提供的equalTo等接口,设置更新条件。
- RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用。
- 删除
调用删除接口,通过AbsRdbPredicates指定删除条件。该接口的返回值表示删除的数据行数,可根据此值判断是否删除成功。如果删除失败,则返回0。
表5 数据库删除API
类名
接口名
描述
RdbStore
int delete(AbsRdbPredicates predicates)
删除数据。
predicates:Rdb谓词,指定了删除操作的表名和条件。AbsRdbPredicates的实现类有两个:RdbPredicates和RawRdbPredicates。
- RdbPredicates:支持调用谓词提供的equalTo等接口,设置更新条件。
- RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用。
- 查询
关系型数据库提供了两种查询数据的方式:
- 直接调用查询接口。使用该接口,会将包含查询条件的谓词自动拼接成完整的SQL语句进行查询操作,无需用户传入原生的SQL语句。
- 执行原生的SQL语句进行查询操作。
表6 数据库查询API
类名
接口名
描述
RdbStore
ResultSet query(AbsRdbPredicates predicates, String[] columns)
查询数据。
- predicates:谓词,可以设置查询条件。AbsRdbPredicates的实现类有两个:RdbPredicates和RawRdbPredicates。
- RdbPredicates:支持调用谓词提供的equalTo等接口,设置查询条件。
- RawRdbPredicates:仅支持设置表名、where条件子句、whereArgs三个参数,不支持equalTo等接口调用。
- columns:规定查询返回的列。
RdbStore
ResultSet querySql(String sql, String[] sqlArgs)
执行原生的用于查询操作的SQL语句。
sql:原生用于查询的sql语句。
sqlArgs:sql语句中占位符参数的值,若select语句中没有使用占位符,该参数可以设置为null。
数据库谓词的使用
关系型数据库提供了用于设置数据库操作条件的谓词AbsRdbPredicates,其中包括两个实现子类RdbPredicates和RawRdbPredicates:
- RdbPredicates:开发者无需编写复杂的SQL语句,仅通过调用该类中条件相关的方法,如equalTo、notEqualTo、groupBy、orderByAsc、beginsWith等,就可自动完成SQL语句拼接,方便用户聚焦业务操作。
- RawRdbPredicates:可满足复杂SQL语句的场景,支持开发者自己设置where条件子句和whereArgs参数。不支持equalTo等条件接口的使用。
类名 |
接口名 |
描述 |
---|---|---|
RdbPredicates |
RdbPredicates equalTo(String field, String value) |
设置谓词条件,满足field字段与value值相等。 |
RdbPredicates |
RdbPredicates notEqualTo(String field, String value) |
设置谓词条件,满足field字段与value值不相等。 |
RdbPredicates |
RdbPredicates beginsWith(String field, String value) |
设置谓词条件,满足field字段以value值开头。 |
RdbPredicates |
RdbPredicates between(String field, int low, int high) |
设置谓词条件,满足field字段在最小值low和最大值high之间。 |
RdbPredicates |
RdbPredicates orderByAsc(String field) |
设置谓词条件,根据field字段升序排列。 |
RawRdbPredicates |
void setWhereClause(String whereClause) |
设置where条件子句。 |
RawRdbPredicates |
void setWhereArgs(List<String> whereArgs) |
设置whereArgs参数,该值表示where子句中占位符的值。 |
查询结果集的使用
关系型数据库提供了查询返回的结果集ResultSet,其指向查询结果中的一行数据,供用户对查询结果进行遍历和访问。ResultSet对外API如下所示。
类名 |
接口名 |
描述 |
---|---|---|
ResultSet |
boolean goTo(int offset) |
从结果集当前位置移动指定偏移量。 |
ResultSet |
boolean goToRow(int position) |
将结果集移动到指定位置。 |
ResultSet |
boolean goToNextRow() |
将结果集向后移动一行。 |
ResultSet |
boolean goToPreviousRow() |
将结果集向前移动一行。 |
ResultSet |
boolean isStarted() |
判断结果集是否被移动过。 |
ResultSet |
boolean isEnded() |
判断结果集当前位置是否在最后一行之后。 |
ResultSet |
boolean isAtFirstRow() |
判断结果集当前位置是否在第一行。 |
ResultSet |
boolean isAtLastRow() |
判断结果集当前位置是否在最后一行。 |
ResultSet |
int getRowCount() |
获取当前结果集中的记录条数。 |
ResultSet |
int getColumnCount() |
获取结果集中的列数。 |
ResultSet |
String getString(int columnIndex) |
获取当前行指定列的值,以String类型返回。 |
ResultSet |
byte[] getBlob(int columnIndex) |
获取当前行指定列的值,以字节数组形式返回。 |
ResultSet |
double getDouble(int columnIndex) |
获取当前行指定列的值,以double型返回。 |
事务
关系型数据库提供事务机制,来保证用户操作的原子性。对单条数据进行数据库操作时,无需开启事务;插入大量数据时,开启事务可以保证数据的准确性。如果中途操作出现失败,会自动执行回滚操作。
类名 |
接口名 |
描述 |
---|---|---|
RdbStore |
void beginTransaction() |
开启事务。 |
RdbStore |
void markAsCommit() |
设置事务的标记为成功。 |
RdbStore |
void endTransaction() |
结束事务。当调用此方法前若执行markAsCommit方法,事务会提交,否则事务会自动回滚。 |
事务和结果集观察者
关系型数据库提供了事务和结果集观察者能力,当对应的事件被触发时,观察者会收到通知。
类名 |
接口名 |
描述 |
---|---|---|
RdbStore |
void beginTransactionWithObserver(TransactionObserver transactionObserver) |
开启事务,并观察事务的启动、提交和回滚。 |
ResultSet |
void registerObserver(DataObserver observer) |
注册结果集的观察者。 |
ResultSet |
void unregisterObserver(DataObserver observer) |
注销结果集的观察者。 |
数据库的备份和恢复
用户可以将当前数据库的数据进行保存备份,还可以在需要的时候进行数据恢复。
类名 |
接口名 |
描述 |
---|---|---|
RdbStore |
boolean restore(String srcName) |
数据库恢复接口,从指定的非加密数据库文件中恢复数据。 |
RdbStore |
boolean restore(String srcName, byte[] srcEncryptKey, byte[] destEncryptKey) |
数据库恢复接口,从指定的数据库文件(加密和非加密均可)中恢复数据。 |
RdbStore |
boolean backup(String destName) |
数据库备份接口,备份出的数据库文件是非加密的。 |
RdbStore |
boolean backup(String destName, byte[] destEncryptKey) |
数据库备份接口,此方法经常用在备份出加密数据库场景。 |
开发步骤
1.创建数据库。
- 配置数据库相关信息,包括数据库的名称、存储模式、是否为只读模式等。
- 初始化数据库表结构和相关数据。
- 创建数据库。
package com.example.sqliteproject.utils;import ohos.app.Context;
import ohos.data.DatabaseHelper;
import ohos.data.rdb.RdbOpenCallback;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.StoreConfig;/*** 创建sqlite数据库的辅助类*/
public class MyHelper extends RdbOpenCallback {DatabaseHelper db;private RdbStore rs;private static MyHelper helper;//单例设计模式public static RdbStore getInstance(Context context,String DBName){if (helper==null)helper=new MyHelper(context,DBName);return helper.rs;}public MyHelper(Context context,String DBName) {db=new DatabaseHelper(context);//创建数据库StoreConfig config=StoreConfig.newDefaultConfig(DBName);rs=db.getRdbStore(config,1,this,null);}@Overridepublic void onCreate(RdbStore rdbStore) {//创建表rdbStore.executeSql("create table if not exists student(id integer primary key autoincrement,name varchar(20),age int ,phone varchar(11),address text)");}@Overridepublic void onUpgrade(RdbStore rdbStore, int i, int i1) {System.out.println("版本已更新");}
}
2.封装DBUtils工具类
- 创建DBUtils类,使用单利设计模式创建构造方法,封装执行增删改查的方法
package com.example.sqliteproject.utils;import ohos.app.Context;
import ohos.data.rdb.RdbPredicates;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.ValuesBucket;
import ohos.data.resultset.ResultSet;/*** 数据库工具类*/
public class DBUtil {public static DBUtil db;private static RdbStore rs;//单例设计模式public static DBUtil getInstance(RdbStore rs){if (db==null)db=new DBUtil();DBUtil.rs=rs;return db;}//添加public long insert(String tableName, ValuesBucket vb){return rs.insert(tableName,vb);}//修改public long update(String tableName, ValuesBucket vb,int id){RdbPredicates rdbPredicates = new RdbPredicates(tableName).equalTo("id",id);return rs.update(vb,rdbPredicates);}//删除public long delete(String tableName, int id){RdbPredicates rdbPredicates = new RdbPredicates(tableName).equalTo("id",id);return rs.delete(rdbPredicates);}//查询public String select(String tableName){String info="";//定义要查询的字段数组String[] columns = new String[] {"id", "name", "age", "phone","address"};//设置要查询的表,以及查询的条件RdbPredicates rdbPredicates = new RdbPredicates(tableName);ResultSet resultSet = rs.query(rdbPredicates, columns);//循环遍历查询的结果集,获得所有查询的数据while (resultSet.goToNextRow()){int id=resultSet.getInt(resultSet.getColumnIndexForName("id"));String name=resultSet.getString(resultSet.getColumnIndexForName("name"));int age=resultSet.getInt(resultSet.getColumnIndexForName("age"));String phone=resultSet.getString(resultSet.getColumnIndexForName("phone"));String address=resultSet.getString(resultSet.getColumnIndexForName("address"));info+=id+"\t"+name+"\t"+age+"\t"+phone+"\t"+address+"\n";}return info;}
}
3.添加数据
- 创建ValuesBucket类将要添加的数据以key-value的形式添加进去,key对应的是数据库表的字段名,value是存储的字段对应的数据。
//添加public long insert(String tableName, ValuesBucket vb){return rs.insert(tableName,vb);}
- 在MainAbilitySlice类中定义按钮,通过点击按钮触发事件将数据封装,调用DBUtils类执行insert方法
//添加
ValuesBucket vb=new ValuesBucket();
vb.putString("name","张三");
vb.putInteger("age",20);
vb.putString("phone","18170072135");
vb.putString("address","江西省南昌市");
long i=DBUtil.getInstance(rs).insert("student",vb);
if (i>0)new ToastDialog(MainAbilitySlice.this).setText("添加成功").show();
4.修改数据
- 将要更新的内容存储在ValuesBucket对象中,将条件数据设置在RdbPredicates对象上
//修改public long update(String tableName, ValuesBucket vb,int id){RdbPredicates rdbPredicates = new RdbPredicates(tableName).equalTo("id",id);return rs.update(vb,rdbPredicates);}
- 在MainAbilitySlice类中定义按钮,通过点击按钮触发事件将数据封装,调用DBUtils类执行update方法
//修改
ValuesBucket vb1=new ValuesBucket();
vb1.putInteger("age",24);
long j=DBUtil.getInstance(rs).update("student",vb1,1);
if (j>0)new ToastDialog(MainAbilitySlice.this).setText("修改成功").show();
5.删除数据
- 将要删除的条件封装在RdbPredicates对象中,根据表名删除符合筛查条件的数据
//删除
public long delete(String tableName, int id){RdbPredicates rdbPredicates = new RdbPredicates(tableName).equalTo("id",id);return rs.delete(rdbPredicates);
}
- 在MainAbilitySlice类中定义按钮,通过点击按钮触发事件将数据封装,调用DBUtils类执行delete方法
//删除long x=DBUtil.getInstance(rs).delete("student",2);if (x>0)new ToastDialog(MainAbilitySlice.this).setText("删除成功").show();
6.查询数据
- 将查询的条件数据和表名封装在RdbPredicates对象中,然后通过RdbStore对象调用query方法获得ResultSet对象,判断是否查询到更多的数据进行循环遍历
//查询public String select(String tableName){String info="";//定义要查询的字段数组String[] columns = new String[] {"id", "name", "age", "phone","address"};//设置要查询的表,以及查询的条件RdbPredicates rdbPredicates = new RdbPredicates(tableName);ResultSet resultSet = rs.query(rdbPredicates, columns);//循环遍历查询的结果集,获得所有查询的数据while (resultSet.goToNextRow()){int id=resultSet.getInt(resultSet.getColumnIndexForName("id"));String name=resultSet.getString(resultSet.getColumnIndexForName("name"));int age=resultSet.getInt(resultSet.getColumnIndexForName("age"));String phone=resultSet.getString(resultSet.getColumnIndexForName("phone"));String address=resultSet.getString(resultSet.getColumnIndexForName("address"));info+=id+"\t"+name+"\t"+age+"\t"+phone+"\t"+address+"\n";}return info;}
- 在MainAbilitySlice类中定义按钮,通过点击按钮触发事件将数据封装,调用DBUtils类执行select方法,将查询的数据显示在text组件上
//查询
String info= DBUtil.getInstance(rs).select("student");
tv_text.setText(info);
7.界面布局搭建
在layout文件夹中添加xml文件,布局搭建的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayoutxmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:height="match_parent"ohos:width="match_parent"ohos:orientation="vertical"><Buttonohos:id="$+id:btn1"ohos:height="match_content"ohos:width="match_parent"ohos:text_size="20vp"ohos:margin="10fp"ohos:padding="10fp"ohos:text_color="#f00"ohos:background_element="$graphic:background_button1"ohos:text="添加"/><Buttonohos:id="$+id:btn2"ohos:height="match_content"ohos:width="match_parent"ohos:text_size="20vp"ohos:margin="10fp"ohos:padding="10fp"ohos:text_color="#f00"ohos:background_element="$graphic:background_button1"ohos:text="修改"/><Buttonohos:id="$+id:btn3"ohos:height="match_content"ohos:width="match_parent"ohos:text_size="20vp"ohos:margin="10fp"ohos:padding="10fp"ohos:text_color="#f00"ohos:background_element="$graphic:background_button1"ohos:text="删除"/><Buttonohos:id="$+id:btn4"ohos:height="match_content"ohos:width="match_parent"ohos:text_size="20vp"ohos:margin="10fp"ohos:padding="10fp"ohos:text_color="#f00"ohos:background_element="$graphic:background_button1"ohos:text="查询"/><Textohos:id="$+id:tv_text"ohos:height="match_content"ohos:width="match_content"ohos:background_element="$graphic:background_ability_main"ohos:layout_alignment="center"ohos:auto_font_size="true"ohos:multiple_lines="true"ohos:text="$string:mainability_HelloWorld"ohos:text_size="30vp"/></DirectionalLayout>
按钮对应的背景样式代码如下:
<?xml version="1.0" encoding="utf-8"?>
<shapexmlns:ohos="http://schemas.huawei.com/res/ohos"ohos:shape="rectangle"><cornersohos:radius="10"/><solidohos:color="#00ff00"/>
</shape>
8.AbilitySlice类的完整代码
package com.example.sqliteproject.slice;import com.example.sqliteproject.ResourceTable;
import com.example.sqliteproject.utils.DBUtil;
import com.example.sqliteproject.utils.MyHelper;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.agp.window.dialog.ToastDialog;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.ValuesBucket;public class MainAbilitySlice extends AbilitySlice {RdbStore rs;private Button btn1,btn2,btn3,btn4;private Text tv_text;@Overridepublic void onStart(Intent intent) {super.onStart(intent);super.setUIContent(ResourceTable.Layout_ability_main);rs=MyHelper.getInstance(getContext(),"StudentDB");btn1= (Button) this.findComponentById(ResourceTable.Id_btn1);btn2= (Button) this.findComponentById(ResourceTable.Id_btn2);btn3= (Button) this.findComponentById(ResourceTable.Id_btn3);btn4= (Button) this.findComponentById(ResourceTable.Id_btn4);tv_text= (Text) this.findComponentById(ResourceTable.Id_tv_text);btn1.setClickedListener(listener);btn2.setClickedListener(listener);btn3.setClickedListener(listener);btn4.setClickedListener(listener);}private Component.ClickedListener listener=new Component.ClickedListener() {@Overridepublic void onClick(Component component) {switch (component.getId()){case ResourceTable.Id_btn1://添加ValuesBucket vb=new ValuesBucket();vb.putString("name","张三");vb.putInteger("age",20);vb.putString("phone","18170072135");vb.putString("address","江西省南昌市");long i=DBUtil.getInstance(rs).insert("student",vb);if (i>0)new ToastDialog(MainAbilitySlice.this).setText("添加成功").show();break;case ResourceTable.Id_btn2://修改ValuesBucket vb1=new ValuesBucket();vb1.putInteger("age",24);long j=DBUtil.getInstance(rs).update("student",vb1,1);if (j>0)new ToastDialog(MainAbilitySlice.this).setText("修改成功").show();break;case ResourceTable.Id_btn3://删除long x=DBUtil.getInstance(rs).delete("student",2);if (x>0)new ToastDialog(MainAbilitySlice.this).setText("删除成功").show();break;case ResourceTable.Id_btn4://查询String info= DBUtil.getInstance(rs).select("student");tv_text.setText(info);break;}}};@Overridepublic void onActive() {super.onActive();}@Overridepublic void onForeground(Intent intent) {super.onForeground(intent);}
}
9.案例效果展示
点击添加按钮,执行添加的操作,点击按钮添加两条数据至数据库,并通过ToastDialog对话框显示添加成功,点击查询按钮可以查询已添加的数据
点击修改,指定了修改主键为1的同学的年龄为24岁,修改成功后,点击查询,可看到被修改后的数据
多添加几条数据并查询出来,点击删除按钮,指定了删除主键为2的同学的记录,再次查询会发现数据库已经不存在主键为2的同学信息,说明删除成功
【鸿蒙】数据管理--关系型数据库相关推荐
- HarmonyOS之数据管理·关系型数据库的应用
一.简介 ① 基本概念 关系型数据库(Relational Database,RDB)是一种基于关系模型来管理数据的数据库.HarmonyOS 关系型数据库基于 SQLite 组件提供了一套完整的对本 ...
- 鸿蒙系统开发者如何加入,鸿蒙开发实战系列之五:鸿蒙系统原生数据库
前言 上文介绍了ObjectBox,属于神器,但是作为一个合格的码农,上的了厅堂,下得了猪圈,神器好用,菜刀也是要会使的嘛,这篇我们就来介绍下鸿蒙系统的数据库如何使用 鸿蒙的关系型数据库是基于SQLi ...
- 鸿蒙开发实战系列之五:鸿蒙系统原生数据库
鸿蒙开发实战系列之一:鸿蒙开发实战系列之一:圆角 鸿蒙开发实战系列之二:鸿蒙开发实战系列之二:事件总线EventBus/RxBus 鸿蒙开发实战系列之三:鸿蒙开发实战系列之三:网络请求(原生+ Ret ...
- 从属关系mysql_关系型数据库基础概念:MySQL系列之开篇
一.基础概念 数据(Data)是描述事物的符号记录,是指利用物理符号记录下来的.可以鉴别的信息. 1.数据库(Database,DB)是指长期储存在计算机中的有组织的.可共享的数据集合.数据要按照一定 ...
- 阿里云新一代关系型数据库 PolarDB 剖析
本文通过描述关系型数据库发展的背景以及云计算的时代特征,分享了数据库计算力的螺旋式上升的进化理念.并且结合阿里云 RDS 产品的发展路径,阐述了自主研发的新一代云托管关系型数据库 PolarDB 的产 ...
- 关系型数据库是如何运作的
一说到关系型数据库,我总感觉缺了点什么.如果你尝试透过"关系型数据库是如何运作的"的关键词句来进行搜索,其搜索结果是少量的而且内容是简短的.难道说是由于它已经太老旧而已经不再流行吗 ...
- 关系型数据库和mysql教材_关系型数据库(MySQL)
数据库系统DBS(DataBase System):数据库管理系统DBMS(DataBase Management System)+数据库DB(DataBase) [关系型数据库]概念: 表table ...
- 1、数据库是什么?关系型数据库和非关系型数据库又是什么?
在学习数据库之前,应该先理解什么是数据.本节先介绍数据以及数据库的概念,再对关系型数据库和非关系型数据库的优缺点进行分析. 描述事物的符号称为数据.数据有多种表现形式,可以是数字,也可以是文字.图形. ...
- nosql非关系型数据库_从Datomic出发,革命性的非NoSQL数据库
nosql非关系型数据库 我终于设法了解了当今最不寻常的数据库之一,Datomic,并希望与您分享. 感谢Stuart Halloway和他的工作室! 为什么?!? 我们很快就会看到,Datomic与 ...
最新文章
- C语言程序设计基础及应用实例---第一节 printf函数的使用
- 不同测试阶段,不同测试类型的区别于联系
- 【2050 Programming Competition - 2050 一万人码 】非官方部分题解(HDU)
- StakeDAO新增Sushiswap流动性奖励计划
- PNG和PVR之间互相转换的脚本
- HWSD土壤数据库介绍
- bouncycastle JAVA实现SM3算法
- c mysql开发工具_Windows平台下Mysql C程序设计
- 奥的斯维修服务器无响应,奥的斯GEN-2电梯故障现象:不定层的平层停梯,外呼无用断电或打检修会恢复还有运行至某层不开门自动去找平...
- 获取KVM虚拟机IP地址
- 阿里P7亲自教你!2021Java不死我不倒
- C++ map通过key获取value
- excel表格拆分多个表如何快速完成?
- cesium获取模型高度_Cesium专栏-空间分析之剖面分析(附源码下载)
- 小程序中css实现镜像功能
- 堆——神奇的优先队列 大根堆小根堆详解,附小根堆C++代码实现与STL相关
- [药品飞检]六大部门检查要点(38个子项目)
- 完美解决微信浏览器内长按识别个人收款码的案例分享
- 你知道 GNU Binutils 吗?
- 在Linux下查看FC HBA卡的速率和状态
热门文章
- 远程桌面服务ActiveX空件(mstscax.dll)跟客服端外壳的版本不相配
- 【论文笔记】Fast and Furious: Real Time End-to-End 3D Detection, Tracking and Motion Forecasting
- 离线计算七 辅助系统(flume、sqoop、oozie)
- Linux noVNC 下载安装、配置、运行
- 【LateX本地配置】TeXLive和TeXstudio软件安装(Latex下载/安装/测试/升级)以及vscode环境配置详细教程
- 洛丽塔服装怎么画?女生的衣服怎么画?
- VBA设置默认/缺省运行路径的方法
- sql笔记1:sql执行优先级和casewhen用法、sql执行顺序
- mysql储存字符串斜杠_MySQL列名中包含斜杠或者空格的处理方法
- oracle查看某个表空间数据增长量,查看表空间每天增长和每周增长情况