浅析开源内存数据库Fastdb

news2025/2/26 4:14:03

介绍:

Fastdb是免费开源内存数据库,其优秀的性能,和简洁的C++代码,让我学习使用过程中收益颇多,但是国内中文相关研究的文章相当稀少,外文我查询相当不便。有兴趣的朋友可以通过以下网站访问:Main Memory Object-Relational Database Management System,相关文档详见:FastDB Main Memory Database Management System。本文将以Windows版本C++版本号3.76为基础进行开发和测试,听说有4.14的版本但是我没有办法获取,有获得新版本的朋友不妨能发我一份学习,我的邮箱:lyfwwb@163.com,在此先行感谢!本文将记录学习相关过程中心得和一些功能分析,希望自己不会忘记曾经使用过的历史和自己改造过程。借此机会给那些和我一样想用的朋友又碰到一样问题的人提供一些思路和方法。希望有人可以给我更好更完善的资料系统学习。很多人认为Fastdb只能本机上进行数据库操作,其实Fastdb在3.76版本中已经提供简单服务端/客户端功能了,有C++编程能力的可以实现更多的功能。框架作者已经做得很好了。

下面是Fastdb官方的介绍译文:

FastDB是一个高效的主存数据库系统,具有实时功能和方便的C++接口。FastDB不支持客户端-服务器体系结构,所有使用FastDB数据库的应用程序都应该在同一主机上运行。FastDB针对具有主导读取访问模式的应用程序进行了优化。通过消除数据传输开销和非常有效的锁定实现,可以提供高速的查询执行。数据库文件被映射到与数据库一起工作的每个应用程序的虚拟内存空间。因此,查询是在应用程序的上下文中执行的,不需要上下文切换和数据传输。并发数据库访问的同步是通过原子指令在FastDB中实现的,几乎不增加查询处理的开销。FastDB假设整个数据库都存在于RAM中,并根据这一假设优化搜索算法和结构。此外,FastDB没有数据库缓冲区管理引起的开销,并且不需要在数据库文件和缓冲池之间进行数据传输。这就是为什么FastDB的工作速度要比所有数据都缓存在缓冲池中的传统数据库快得多。

FastDB支持事务处理、在线备份和系统崩溃后的自动恢复。事务提交协议基于影子根页算法,执行数据库的原子更新。恢复可以非常快速地完成,为关键应用程序提供高可用性。此外,事务日志的消除提高了整个系统的性能,并使系统资源得到更有效的利用。

FastDB是一个面向应用程序的数据库。数据库表是使用有关应用程序类的信息构建的。FastDB支持自动方案评估,允许您只在一个地方进行更改——在应用程序类中。FastDB为从数据库中检索数据提供了一个灵活方便的接口。使用类似SQL的查询语言来指定查询。非原子字段、嵌套数组、用户定义的类型和方法、直接的对象间引用等后关系功能简化了数据库应用程序的设计,提高了它们的效率。

尽管FastDB是在假设数据库作为一个整体适合计算机的物理内存的情况下进行优化的,但也可以将其与数据库一起使用,因为数据库的大小超过了系统中物理内存的大小。在最后一种情况下,标准操作系统交换机制将起作用。但所有FastDB搜索算法和结构都是在所有数据都驻留在内存中的假设下进行优化的,因此交换数据的效率不会很高。

功能模块的分析与介绍

1、查询语言介绍:

FastDB支持具有类似SQL语法的查询语言。FastDB使用的符号在面向对象编程中比在关系数据库中更受欢迎。表行被视为对象实例,表是这些对象的类。与SQL不同,FastDB面向的是使用对象,而不是SQL元组。因此,每次查询执行的结果都是一个类的一组对象。FastDB查询语言与标准SQL的主要区别在于:

1、 没有几个表和嵌套子查询的联接。查询总是从一个表中返回一组对象。

2、 标准C类型用于原子表列。

3、 除了空引用之外,没有空值。我完全同意C.J.Date对三值逻辑的批评,以及他使用默认值的建议。

4、 结构和数组可以用作记录组件。提供了一个特殊的存在量化器来定位数组中的元素。

5、 可以为表记录(对象)以及记录组件定义无参数用户方法。

6、 应用程序可以定义(只有)一个字符串或数字参数的用户函数。

7、 支持对象之间的引用,包括对反向引用的自动支持。

8、 从后面开始的构造使用引用执行递归记录遍历。

9、 由于查询语言被深度集成到C++类中,因此对语言标识符和关键字都使用了区分大小写的模式。

10、 没有完成整数和浮点类型到字符串表示形式的隐式转换。如果需要这样的转换,就必须明确地进行。

下面以类似BNF的符号表示法规定了FastDB查询语言搜索谓词的语法:

标识符区分大小写,以a-z、a-z、'_'或'$'字符开头,仅包含a-z、a-z、0-9、'_‘或'$‘字符,并且不重复SQL保留字。

保留字列表 
absandascbetweenby
currentdescescapeexistsfalse
firstfollowfromininteger
islengthlikelastlower
matchnotnullorreal
startstringtrueupper

也可以使用ANSI标准注释。双连字符后直到行尾的所有字符都将被忽略。

FastDB通过支持位操作来扩展ANSI标准SQL操作。运算符and/or不仅可以应用于布尔操作数,还可以应用于整数类型的操作数。将and/or运算符应用于整数操作数的结果是通过位and/位or运算设置位的整数值。位操作可以用于小集合的有效实现。此外,对于整数和浮点类型,FastDB也支持对幂运算(x^y)的引用。

2、结构

FastDB接受结构作为记录的组成部分。可以使用标准点表示法访问结构的字段如 :company.address.city

结构字段可以按规范的顺序进行索引和使用。结构可以包含其他结构作为其组件;嵌套级别没有限制。

程序员可以定义结构的方法,这些方法可以在查询中使用与正常结构组件相同的语法。这样的方法除了指向它所属对象的指针(C++中的this指针)之外,不应该有任何参数,并且应该返回一个原子值(布尔值、数值、字符串或引用类型)。此外,该方法不应更改对象实例(不可变方法)。如果该方法返回一个字符串,则应该使用new char数组空间 来分配该字符串,因为临时变量将在复制其值后被删除。

因此,用户定义的方法可以用于创建虚拟组件——这些组件不存储在数据库中,而是使用其他组件的值进行计算。例如,FastDB dbDateTime类型仅包含整数时间戳组件和dbDateTime::year()、dbDateTime::month()等方法。。。因此,可以在应用程序中指定诸如“deliveryy.year=1999”之类的查询,其中交付记录字段具有dbDateTime类型。方法是在定义它们的应用程序上下文中执行的,其他应用程序和交互式SQL不可用。

3、数组

FastDB接受具有动态长度的数组作为记录的组成部分。不支持多维数组,但可以定义数组的数组。可以按数组字段的长度对结果集中的记录进行排序。FastDB提供了一组用于处理数组的特殊构造:

通过length()函数可以获得数组中元素的数量。

数组元素可以由[]运算符提取。如果索引表达式超出数组范围,将引发异常。

中的运算符可用于检查数组是否包含由左操作数指定的值。此操作只能用于原子类型的数组:具有布尔值、数值、引用或字符串组件。

数组可以使用update方法更新,该方法创建数组的副本并返回非常量引用。

数组元素的迭代由exists运算符执行。在exists关键字之后指定的变量可以用作exists量化器前面的表达式中数组的索引。此索引变量将遍历所有可能的数组索引值,直到表达式的值变为true或索引超出范围。条件

  exists i: (contract[i].company.location = 'US')

将选择位于“美国”的公司发货的所有详细信息,而查询

 not exists i: (contract[i].company.location = 'US')

将选择从“美国”以外的公司发货的所有详细信息。

允许嵌套的exists子句。使用嵌套的exists量化器相当于使用对应索引变量的嵌套循环。例如查询

    exists i: (contract[i].company.location = 'US')

将选择所有记录,在矩阵字段的元素中包含0,该字段的类型为array或array of integer。此构造等效于以下两个嵌套循环:

 bool result = false;
       for (int column = 0; column < matrix.length(); column++) { 
            for (int row = 0; row < matrix[column].length(); row++) { 
             if (matrix[column][row] == 0) { 
                     result = true;
             break;
                 }
            }
       }

使用索引的顺序至关重要!以下查询执行的结果

  exists row: (exists column: (matrix[column][row] = 0))

将与上一次查询的结果完全不同。在最后一种情况下,在空矩阵的情况下,程序只是由于无限循环而挂起。

4、字符串

FastDB中的所有字符串都有不同的长度,程序员不应该担心字符字段的最大长度的指定。数组可接受的所有操作也适用于字符串。除了它们之外,字符串还有一组自己的操作。首先,可以使用标准关系运算符将字符串相互比较。目前,FastDB只支持ASCII字符集(对应于C中的char类型)和忽略位置设置的逐字节字符串比较。

类似的运算符可用于将字符串与包含特殊通配符“%”和“_”的模式进行匹配。字符“_”与任何单个字符匹配,而字符“%”与零个或多个字符匹配。如果模式中的字符“%”和“_”前面有一个特殊的转义符(在转义关键字之后指定),则可以使用类似运算符的扩展形式和转义关键字将它们作为普通字符处理。

如果您使用USE_REGEX宏重建GigaBASE,那么您可以使用实现标准正则表达式的匹配运算符(基于GNU正则表达式库)。此运算符的第二个操作数指定了要匹配的正则表达式,并且应该是字符串文字。

可以通过in运算符搜索字符串中的子字符串。对于颜色字段包含“蓝色”的所有记录,表达式(颜色为“蓝色”)都将为true。如果搜索字符串的长度大于某个阈值(当前为512),则使用Boyer-Moore子字符串搜索算法,而不是直接的搜索实现。

字符串可以通过+或||运算符连接。最后一个是为了与ANSI SQL标准兼容而添加的。由于FastDB不支持在表达式中隐式转换为字符串类型,因此可以为字符串重新定义运算符+的语义。

Fastdb是一个面向对象的数据库系统,其主要目标是提供高效的、易于使用的数据存储和检索机制。本文将详细介绍Fastdb的特点和使用方法,并解释所有相关的接口。

一、特点

1. 高效性:Fastdb使用预分配对象的方式,减少了向磁盘分配空间的时间开销。它还使用了内存映射I/O技术,有效地减少了基于文件的I/O操作。

2. 安全性:Fastdb使用了事务机制,可以保证对数据的完整性。而且,它提供了可选的数据加密机制,以保护敏感数据。

3. 易于使用:Fastdb提供了面向对象的API,使得程序员可以快速、直接地存储和检索对象。同时,Fastdb提供了具有强大查询能力的索引机制,以便更高效地定位数据。

4. 可扩展性:Fastdb支持多种语言的接口,包括C++、Java、Python等,可以方便地与其他软件集成。

5. 易于部署:Fastdb是一个轻量级的数据库系统,可以很容易地安装和配置。

二、安装

Fastdb针对不同的操作系统提供了不同的安装包,可在其官方网站上下载。安装过程可以根据安装向导进行,也可以使用命令行方式安装。

三、使用

1. 创建数据库

在使用Fastdb之前,我们需要先创建一个数据库。可以通过以下代码创建并打开一个名为“MyDB”、大小为100MB的数据库:

```
  //创建数据库
  db_open("MyDB", 100000000);
  //获取根对象
  dbDatabase* db = dbDatabase::instance();
```

2. 定义对象

Fastdb的对象被定义为类,需要继承于dbObject类。例如,下面定义了一个Person类:

```
  class Person : public dbObject
  {
  public:
      char* name;
      int age;
      dbReference<Person> father;
      dbReference<Person> mother;
      dbArray<dbReference<Person> > children;
  };
```

在这个类中,我们定义了Person的姓名、年龄、父亲、母亲和孩子。dbReference表示一个对象引用,dbArray表示一个对象数组。dbObject类提供了一些常用的函数,例如dbObject::dbObject()、dbObject::~dbObject()、dbObject::clear()等。

3. 存储对象

我们可以使用dbDatabase::addObject()函数将一个新对象添加到数据库中,并返回一个dbReference对象。

```
  //创建一个新的Person对象并存储到数据库中
  Person* p = new Person;
  p->name = "Lucy";
  p->age = 25;
  dbReference<Person> ref = db->addObject(p);
```

4. 查询对象

Fastdb支持多种条件查询方式,可以快速地查找到我们需要的对象。例如,我们可以使用以下代码查找年龄为25岁的人:

```
  //查询年龄为25的人
  dbQuery q;
  q = db->createQuery();
  q.constrain(Person::age, opEqual, 25);
  q.execute();
  while (q.next()) {
      Person* p = q.object();
      cout << p->name << endl;
  }
```

其中,opEqual表示相等条件,还支持opLess、opGreater等。使用dbQuery::execute()函数执行查询,dbQuery::next()函数将游标移到下一个符合要求的对象位置,dbQuery::object()函数返回当前对象的指针。

5. 更新对象

我们可以使用dbDatabase::updateObject()函数更新已经存在的对象。例如,我们可以修改25岁的Lucy的名字:

```
  //修改Lucy的名字
  q = db->createQuery();
  q.constrain(Person::name, opEqual, "Lucy");
  q.constrain(Person::age, opEqual, 25);
  q.execute();
  while (q.next()) {
      Person* p = q.object();
      p->name = "Lucy Li";
      db->updateObject(p);
  }
```

6. 删除对象

我们可以使用dbDatabase::deleteObject()函数删除已经存在的对象。例如,我们可以删除所有年龄大于30岁的人:

```
  //删除年龄大于30的人
  q = db->createQuery();
  q.constrain(Person::age, opGreater, 30);
  q.execute();
  while (q.next()) {
      Person* p = q.object();
      db->deleteObject(p);
  }
```

四、接口解释

dbDatabase类

1. dbDatabase()

函数说明:构造函数,创建一个数据库对象。

2. static dbDatabase* instance()

函数说明:获取数据库的全局实例。

3. void open(const char* name, int size)

参数说明:name-数据库名称,size-数据库大小(字节)。

函数说明:打开一个数据库文件,并将它设置为当前数据库。

4. void close()

函数说明:关闭数据库文件。

5. dbReference<T> addObject(T* obj)

参数说明:obj-要添加的对象。

函数说明:将一个新对象添加到数据库末尾,并返回一个引用。

6. void updateObject(T* obj)

参数说明:obj-要更新的对象。

函数说明:将一个已经存在的对象更新到数据库中。

7. void deleteObject(T* obj)

参数说明:obj-要删除的对象。

函数说明:从数据库中删除一个已经存在的对象。

8. int commit()

函数说明:提交所有的事务。

9. void rollback()

函数说明:回滚所有的事务。

10. dbQuery createQuery()

函数说明:创建一个查询对象。

11. template <class T> dbReference<T> getReference(T* obj)

参数说明:obj-对象。

函数说明:获取一个对象的引用。

dbQuery类

1. dbQuery(dbDatabase* db)

参数说明:db-数据库对象。

函数说明:构造函数。

2. ~dbQuery()

函数说明:析构函数。

3. void close()

函数说明:关闭查询对象。

4. void reset()

函数说明:重置查询条件。

5. void constrain(dbFieldDescriptor* fd, dbComparisonOperator op, const void* value)

参数说明:fd-一个字段描述器,op-比较操作符,value-比较值。

函数说明:增加一个查询条件。

6. void orderBy(dbFieldDescriptor* fd, bool ascending=true)

参数说明:fd-一个字段描述器,ascending-是否升序排列。

函数说明:指定排序方式。

7. void select(const char* fieldName)

参数说明:fieldName-要返回的字段名称。

函数说明:指定要返回的字段。

8. bool execute()

函数说明:执行查询。

9. bool next()

函数说明:移动游标到下一个结果。

10. dbReference<T> object()

函数说明:返回当前游标所指向的对象引用。

dbFieldDescriptor类

1. dbFieldDescriptor(const char* name, int type, size_t length, int flags)

参数说明:name-字段名称,type-字段类型(int、float、double、char[]等),length-字段长度(对于char[]类型的字段有用),flags-字段属性(比如索引)。

函数说明:构造函数。

dbReference类

1. bool operator== (const dbReference& r)

参数说明:r-一个引用。

函数说明:判断两个引用是否相等。

2. bool operator!= (const dbReference& r)

参数说明:r-一个引用。

函数说明:判断两个引用是否不相等。

3. operator const T* ()

函数说明:将引用转换为指向T类型的指针。

dbArray类

1. dbArray<T>()

函数说明:构造函数。

2. void resize(int n, bool save=true)

参数说明:n-新数组大小,save-是否保留旧数据。

函数说明:重新调整数组大小。

3. void clear()

函数说明:清空数组内容。

4. void add(const T& item)

参数说明:item-要添加的项。

函数说明:将一个项添加到数组末尾。

5. T& operator[](int i) const

参数说明:i-数组下标。

函数说明:获取指定下标的项。

6. int length()

函数说明:获取数组长度。

以上就是Fastdb的详细介绍和所有接口的解释,希望对大家有用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1504894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java-ssm-jsp基于ssm的冰淇淋在线购买网站

java-ssm-jsp基于ssm的冰淇淋在线购买网站 获取源码——》公主号&#xff1a;计算机专业毕设大全

【STM32】HAL库 CubeMX 教程 --- 通用定时器 TIM2 定时

实验目标&#xff1a; 通过CUbeMXHAL&#xff0c;配置TIM2&#xff0c;1s中断一次&#xff0c;闪烁LED。 一、常用型号的TIM时钟频率 1. STM32F103系列&#xff1a; 所有 TIM 的时钟频率都是72MHz&#xff1b;F103C8不带基本定时器&#xff0c;F103RC及以上才带基本定时器。…

react实战——react旅游网

慕课网react实战 搭建项目问题1.按照官网在index.tsx中引入antd出错&#xff1f;2.typescript中如何使用react-router3.react-router3.1 V63.2 V53.3V6实现私有路由 4.函数式组件接收props参数时定义数据接口&#xff1f;5.使用TypeScript开发react项目&#xff1a;6.要使一个组…

探索stable diffusion的奇妙世界--01

目录 1. 理解prompt提示词&#xff1a; 2. Prompt中的技术参数&#xff1a; 3. Prompt中的Negative提示词&#xff1a; 4. Prompt中的特殊元素&#xff1a; 5. Prompt在stable diffusion中的应用&#xff1a; 6. 作品展示&#xff1a; 在AI艺术领域&#xff0c;stable di…

数据结构——线性表顺序表示详解

目录 1.线性表的类型定义 2.基本操作 3.线性表的存储结构 4.补充 1.元素类型说明 2.数组定义​编辑 3.c语言的内存动态分配 4.c的动态存储分配 5.c中的参数传递 引用类型作参数 6.顺序表基本操作的实现 1.线性表的初始化 代码示例&#xff1a; 2.销毁线性表&…

远程连接Linux系统

图形化、命令行 对于操作系统的使用&#xff0c;有2种使用形式&#xff1a; 图形化页面使用操作系统 图形化&#xff1a;使用操作系统提供的图形化页面&#xff0c;以获得图形化反馈的形式去使用操作系统。 以命令的形式使用操作系统 命令行&#xff1a;使用操作系统提供的各…

腾讯云轻量服务器Windows系统使用IIS实现公网直链访问文件

windows方便所以服务器装的windows系统&#xff0c;windows默认不能分享文件直链&#xff0c;只要用IIS建个站点就行了 先弄一台有公网ip的windows系统服务器打开服务器管理器&#xff0c;添加这个 打开IIS右键添加网站 程序池默认&#xff0c;路径选个文件夹作为网站根目录 …

tomcat通过service.bat install方式安装,内存不够了怎么办?

1.通过service.bat安装 安装命令再tomcat的bin目录下&#xff0c;执行命令 .\service.bat install Apache Tomcat 8.5 Tomcat8之后就会在服务里面有个tomcat服务 2. 如何增加tomcat内存呢&#xff1f; 通过service.bat安装肯定再service.bat中配置啊。 再service.bat文件中…

RHCE——一、OpenEuler22.03安装部署及例行性任务

RHCE 一、OpenEuler22.03安装部署及例行性任务 一、网络服务1.准备工作2、RHEL9操作系统的安装部署3、配置并优化OpenEuler22.034、网络配置实验&#xff1a;修改网络配置 二、例行性工作1、 单一执行的例行性任务&#xff1a;at&#xff08;一次性&#xff09;at命令详解 2、循…

MQTT连接阿里云物联网上报物模型数据

目录 1. 创建产品&#xff08;物联网平台 -> 产品 -> 创建产品&#xff09; 2. 为产品添加设备 3. 添加物模型 4. mqtt.fx连接测试 5. 调试物模型 6. 使用mqtt.fx上报温度数据 1. 创建产品&#xff08;物联网平台 -> 产品 -> 创建产品&#xff09; 我这里再新…

企业内部培训考试系统首页自定义版块说明

企业内部培训考试系统首页自定义版块说明&#xff0c;企业内部培训考试系统手机端首页设计太灵活。 1、整站主题色自定义&#xff0c;更换主题色后&#xff0c;重要的文字和按钮颜色都自动使用主题色渲染&#xff0c;相当于一键换皮肤。 2、首页背景图自定义&#xff0c;想换…

【蓝牙协议栈】【经典蓝牙】【BLE蓝牙】蓝牙技术特点

目录 1. 蓝牙技术特点 2. 经典蓝牙与BLE蓝牙对比 2.1 BT/BLE技术区分 2.2 支持的profile不同 2.3 核心架构&#xff0c;不同的controler 3. Bluetooth的系统构成 4. 蓝牙协议规范 4.1 传输协议 4.2 中介协议 4.3 应用协议 5. 蓝牙硬件接口 1. 蓝牙技术特点 简单地说…

论文笔记:Compact Multi-Party Confidential Transactions

https://link.springer.com/chapter/10.1007/978-3-030-65411-5_21 A compact, private, Multi-Party Confidential Transactions (MCT) 紧凑型多方机密交易&#xff08;Compact MCT&#xff09;&#xff1a;MCT的长度与常规的单一所有者交易一样短&#xff1b;换句话说&…

【STM32+HAL】GY25倾斜度角度模块

一、前言 有关MPU6050模块读取六轴传感器数值的详细内容&#xff0c;详见【STM32HAL】姿态传感器陀螺仪MPU6050模块 二、所用工具 1、芯片&#xff1a;STM32F103C8T6 2、配置软件&#xff1a;CUBEMX 3、编译器&#xff1a;KEIL5 4、产品型号&#xff1a;GY-25 5、使用芯片…

【SpringMVC】RESTFul风格设计和实战 第三期

文章目录 概述一、 RESTFul风格简介二、 RESTFul风格特点三、 RESTFul风格设计规范3.1 HTTP协议请求方式要求3.2 URL路径风格要求 实战一、需求分析二、RESTFul风格接口设计三、后台接口实现总结模糊查询 有范围 返回多数据用户 添加 与 更新 请求参数接收数据显示用户详情/删除…

配电网数字化转型全面推进:《关于新形势下配电网高质量发展的指导意见》

近日&#xff0c;国家发展改革委、国家能源局印发了《关于新形势下配电网高质量发展的指导意见》&#xff08;以下简称《意见》&#xff09;&#xff0c;到2030年&#xff0c;基本完成配电网柔性化、智能化、数字化转型&#xff0c;实现主配微网多级协同、海量资源聚合互动、多…

Unity3d C#实现文件(json、txt、xml等)加密、解密和加载(信息脱敏)功能实现(含源码工程)

前言 在Unity3d工程中经常有需要将一些文件放到本地项目中&#xff0c;诸如json、txt、csv和xml等文件需要放到StreamingAssets和Resources文件夹目录下&#xff0c;在程序发布后这些文件基本是对用户可见的状态&#xff0c;造成信息泄露&#xff0c;甚至有不法分子会利用这些…

【Node.js】-闲聊:前端框架发展史

前端框架的发展史是一个不断演进和创新的过程&#xff0c;旨在提高开发效率、优化用户体验&#xff0c;并推动前端技术的不断发展。以下是前端框架发展的主要阶段和关键里程碑&#xff1a; 早期阶段&#xff1a; 在这个阶段&#xff0c;前端主要由HTML、CSS和JavaScript等基础技…

机器学习周报第32周

目录 摘要Abstract一、文献阅读1.论文标题2.论文摘要3.论文背景4.论文方案4.1 多视角自注意力网络4.2 距离感知4.3 方向信息4.4 短语模式 二、self-attention 摘要 本周学习了多视角自注意力网络&#xff0c;在统一的框架下联合学习输入句子的不同语言学方面。具体来说&#x…

HTML5:七天学会基础动画网页10

继续介绍3D转换: 3D转换:rotate3d 方法与说明 rrotateX(angle)otate3d(x,y,z,angle[角度]) 3D转换&#xff0c;正常取值0/1&#xff0c;0代表当前轴线不进行旋转&#xff0c;1反之&#xff0c;例:rotate3d(1,1,1,30deg)&#xff0c;代表三个轴线都要旋转30度 rotate3d(0…