精华内容
下载资源
问答
  • 2020-03-27 14:47:20

    1. 创建

    创建记录:

    user := User{Name: "Jinzhu", Age: 18, Birthday: time.Now()}
    
    db.NewRecord(user) // => 主键为空返回`true`
    
    db.Create(&user)
    
    db.NewRecord(user) // => 创建`user`后返回`false`
    

    设置默认值:
    可以在gorm tag中定义默认值,然后插入SQL将忽略具有默认值的这些字段,并且其值为空,并且在将记录插入数据库后,gorm将从数据库加载这些字段的值。

    type Animal struct {
        ID   int64
        Name string `gorm:"default:'galeone'"`
        Age  int64
    }
    
    var animal = Animal{Age: 99, Name: ""}
    db.Create(&animal)
    
    INSERT INTO animals("age") values('99');
    SELECT name from animals WHERE ID=111; // 返回主键为 111
    animal.Name => 'galeone'
    

    2. 查询

    获取:第一条记录/ 最后一条记录/ 所有记录

    // 获取第一条记录,按主键排序
    db.First(&user)
     SELECT * FROM users ORDER BY id LIMIT 1;
    
    // 获取最后一条记录,按主键排序
    db.Last(&user)
     SELECT * FROM users ORDER BY id DESC LIMIT 1;
    
    // 获取所有记录
    db.Find(&users)
     SELECT * FROM users;
    
    // 使用主键获取记录
    db.First(&user, 10)
     SELECT * FROM users WHERE id = 10;
    

    Where查询条件

    // 获取第一个匹配记录
    db.Where("name = ?", "jinzhu").First(&user)
     SELECT * FROM users WHERE name = 'jinzhu' limit 1;
    
    // 获取所有匹配记录
    db.Where("name = ?", "jinzhu").Find(&users)
     SELECT * FROM users WHERE name = 'jinzhu';
    // IN
    db.Where("name in (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users)
    
    // LIKE
    db.Where("name LIKE ?", "%jin%").Find(&users)
    
    // AND
    db.Where("name = ? AND age >= ?", "jinzhu", "22").Find(&users)
    
    
    

    注意:当使用struct查询时,GORM将只查询那些具有值的字段

    // Struct
    db.Where(&User{Name: "zhangyang", Age: 20}).First(&user)
     SELECT * FROM users WHERE name = "zhangyang" AND age = 20 LIMIT 1;
    
    // Map
    db.Where(map[string]interface{}{"name": "zhangyang", "age": 20}).Find(&users)
     SELECT * FROM users WHERE name = "zhangyang" AND age = 20;
    
    // 主键的Slice
    db.Where([]int64{20, 21, 22}).Find(&users)
     SELECT * FROM users WHERE id IN (20, 21, 22);
    

    Not条件查询

    db.Not("name", "jinzhu").First(&user)
     SELECT * FROM users WHERE name <> "jinzhu" LIMIT 1;
    
    // Not In
    db.Not("name", []string{"jinzhu", "jinzhu 2"}).Find(&users)
     SELECT * FROM users WHERE name NOT IN ("jinzhu", "jinzhu 2");
    
    // Not In slice of primary keys
    db.Not([]int64{1,2,3}).First(&user)
     SELECT * FROM users WHERE id NOT IN (1,2,3);
    
    db.Not([]int64{}).First(&user)
     SELECT * FROM users;
    

    Or条件查询

    db.Where("role = ?", "admin").Or("role = ?", "super_admin").Find(&users)
     SELECT * FROM users WHERE role = 'admin' OR role = 'super_admin';
    
    // Struct
    db.Where("name = 'jinzhu'").Or(User{Name: "jinzhu 2"}).Find(&users)
     SELECT * FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2';
    

    Select 指定要从数据库检索的字段,默认情况下,将选择所有字段;

    db.Select("name, age").Find(&users)
     SELECT name, age FROM users;
    
    db.Select([]string{"name", "age"}).Find(&users)
     SELECT name, age FROM users;
    

    Order

    db.Order("age desc, name").Find(&users)
     SELECT * FROM users ORDER BY age desc, name;
    
    // Multiple orders
    db.Order("age desc").Order("name").Find(&users)
     SELECT * FROM users ORDER BY age desc, name;
    
    // ReOrder 从数据库检索记录时指定顺序,将重排序设置为true以覆盖定义的条件
    db.Order("age desc").Find(&users1).Order("age", true).Find(&users2)
     SELECT * FROM users ORDER BY age desc; (users1)
     SELECT * FROM users ORDER BY age; (users2)
    

    Limit , Offset
    指定要检索的记录数

    db.Limit(3).Find(&users)
     SELECT * FROM users LIMIT 3;
    

    指定在开始返回记录之前要跳过的记录数

    db.Offset(3).Find(&users)
     SELECT * FROM users OFFSET 3;
    
    // Cancel offset condition with -1
    db.Offset(10).Find(&users1).Offset(-1).Find(&users2)
     SELECT * FROM users OFFSET 10; (users1)
     SELECT * FROM users; (users2)
    

    Count,Group & Having,Join
    获取记录数

    db.Where("name = ?", "jinzhu").Or("name = ?", "jinzhu 2").Find(&users).Count(&count)
     SELECT * from USERS WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (users)
     SELECT count(*) FROM users WHERE name = 'jinzhu' OR name = 'jinzhu 2'; (count)
    
    db.Model(&User{}).Where("name = ?", "jinzhu").Count(&count)
     SELECT count(*) FROM users WHERE name = 'jinzhu'; (count)
    
    //指定表deleted_users
    db.Table("deleted_users").Count(&count)
    //
    
    rows, err := db.Table("orders").Select("date(created_at) as date, sum(amount) as total").Group("date(created_at)").Rows()
    
    rows, err := db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Rows()
    

    3. 更新

    更新全部字段
    Save将包括执行更新SQL时的所有字段,即使它没有更改

    db.First(&user)
    
    user.Name = "jinzhu 2"
    user.Age = 100
    db.Save(&user)
    
     UPDATE users SET name='jinzhu 2', age=100, birthday='2016-01-01', updated_at = '2013-11-17 21:34:10' WHERE id=111;
    

    更新指定字段
    如果只想更新指定字段,可以使用Update, Updates

    // 更新单个属性(如果更改)
    db.Model(&user).Update("name", "hello")
     UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
    
    // 使用组合条件更新单个属性
    db.Model(&user).Where("active = ?", true).Update("name", "hello")
     UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111 AND active=true;
    
    // 使用`map`更新多个属性,只会更新这些更改的字段
    db.Model(&user).Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
     UPDATE users SET name='hello', age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
    
    // 使用`struct`更新多个属性,只会更新这些更改的和非空白字段
    db.Model(&user).Updates(User{Name: "hello", Age: 18})
     UPDATE users SET name='hello', age=18, updated_at = '2013-11-17 21:34:10' WHERE id = 111;
    
    // 警告:当使用struct更新时,FORM将仅更新具有非空值的字段
    // 对于下面的更新,什么都不会更新为"",0,false是其类型的空白值
    db.Model(&user).Updates(User{Name: "", Age: 0, Actived: false})
    

    更新选择的字段
    如果您只想在更新时更新或忽略某些字段,可以使用Select, Omit

    db.Model(&user).Select("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
     UPDATE users SET name='hello', updated_at='2013-11-17 21:34:10' WHERE id=111;
    
    db.Model(&user).Omit("name").Updates(map[string]interface{}{"name": "hello", "age": 18, "actived": false})
     UPDATE users SET age=18, actived=false, updated_at='2013-11-17 21:34:10' WHERE id=111;
    

    4. 删除

    警告:删除记录时,需要确保其主要字段具有值,GORM将使用主键删除记录,如果主要字段为空,GORM将删除模型的所有记录

    // 删除存在的记录
    db.Delete(&email)
     DELETE from emails where id=10;
    
    // 为Delete语句添加额外的SQL选项
    db.Set("gorm:delete_option", "OPTION (OPTIMIZE FOR UNKNOWN)").Delete(&email)
     DELETE from emails where id=10 OPTION (OPTIMIZE FOR UNKNOWN);
    

    批量删除
    删除所有匹配记录

    db.Where("email LIKE ?", "%jinzhu%").Delete(Email{})
     DELETE from emails where email LIKE "%jinhu%";
    
    db.Delete(Email{}, "email LIKE ?", "%jinzhu%")
     DELETE from emails where email LIKE "%jinhu%";
    
    更多相关内容
  • 在为SQL SERVER创建ORACLE的连接服务器时,没有ORACLE provider for OLE DB 的连接服务驱动。经网上搜索,把PDF安装说明和驱动程序一起收藏,请各位下载;
  • IndexedDB详解

    万次阅读 2021-01-11 11:00:49
    IndexedDB是一种在浏览器端存储数据的方式。既然称之为DB,是因为它丰富了客户端的查询方式,并且因为是本地存储,可以有效的减少网络对页面数据的影响。 有了IndexedDB,浏览器可以存储更多的数据,从而丰富了...

    简介

    IndexedDB是一种在浏览器端存储数据的方式。既然称之为DB,是因为它丰富了客户端的查询方式,并且因为是本地存储,可以有效的减少网络对页面数据的影响。

    有了IndexedDB,浏览器可以存储更多的数据,从而丰富了浏览器端的应用类型。

    IndexedDB简介

    IndexedDB和传统的关系型数据不同的是,它是一个key-value型的数据库。

    value可以是复杂的结构体对象,key可以是对象的某些属性值也可以是其他的对象(包括二进制对象)。你可以使用对象中的任何属性做为index,以加快查找。

    IndexedDB是自带transaction的,所有的数据库操作都会绑定到特定的事务上,并且这些事务是自动提交了,IndexedDB并不支持手动提交事务。

    IndexedDB API大部分都是异步的,在使用异步方法的时候,API不会立马返回要查询的数据,而是返回一个callback。

    异步API的本质是向数据库发送一个操作请求,当操作完成的时候,会收到一个DOM event,通过该event,我们会知道操作是否成功,并且获得操作的结果。

    IndexedDB是一种 NoSQL 数据库,和关系型数据库不同的是,IndexedDB是面向对象的,它存储的是Javascript对象。

    IndexedDB还有一个很重要的特点是其同源策略,每个源都会关联到不同的数据库集合,不同源是不允许访问其他源的数据库,从而保证了IndexedDB的安全性。

    IndexedDB的使用

    这一节,我们将会以具体的例子来讲解如何使用IndexedDB。

    IndexedDB的浏览器支持

    不同的浏览器对于IndexedDB有不同的实现,正常来说,我们可以使用window.indexedDB来获取到浏览器的indexedDB对象。但是对于某些浏览器来说,还没有使用标准的window.indexedDB,而是用带前缀的实现。

    所以我们在使用过程中通常需要进行判断和转换:

    // In the following line, you should include the prefixes of implementations you want to test.
    window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
    // DON'T use "var indexedDB = ..." if you're not in a function.
    // Moreover, you may need references to some window.IDB* objects:
    window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction || {READ_WRITE: "readwrite"}; // This line should only be needed if it is needed to support the object's constants for older browsers
    window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
    // (Mozilla has never prefixed these objects, so we don't need window.mozIDB*)
    

    上面我们从window获取了indexedDB,IDBTransaction和IDBKeyRange三个对象。

    其中indexedDB表示的是数据库的连接。IDBTransaction表示的是transaction,而IDBKeyRange则是用从数据库的某个特定key range中取出数据。

    但是,通常来说带前缀的实现一般都是不稳定的,所以我们通常不建议在正式环境中使用,所以如果不支持标准表达式的话,需要直接报错:

    if (!window.indexedDB) {
        console.log("Your browser doesn't support a stable version of IndexedDB. Such and such feature will not be available.");
    }
    

    创建IndexedDB

    要使用IndexedDB,我们首先需要open it:

    // Let us open our database
    var request = window.indexedDB.open("MyTestDatabase", 3);
    

    open方法返回一个IDBOpenDBRequest对象,同时这是一个异步操作,open操作并不会立马打开数据库或者开启事务,我们可以通过监听request的事件来进行相应的处理。

    open方法传入两个参数,第一个参数是数据库的名字,第二个参数是数据库的版本号。

    当你创建一个新的数据库或者升级一个现有的数据库版本的时候,将会触发一个onupgradeneeded事件,并在事件中传入IDBVersionChangeEvent,我们可以通过event.target.result来获取到IDBDatabase对象,然后通过这个对象来进行数据库的版本升级操作。如下所示:

    // This event is only implemented in recent browsers   
    request.onupgradeneeded = function(event) { 
      // Save the IDBDatabase interface 
      var db = event.target.result;
    
      // Create an objectStore for this database
      var objectStore = db.createObjectStore("name", { keyPath: "myKey" });
    };
    

    注意,这里的版本号是一个整数。如果你传入一个float,那么将会对该float进行取整操作。

    有了request,我们可以通过监听onerror或者onsuccess事件来进行相应的处理。

    var db;
    var request = indexedDB.open("MyTestDatabase");
    request.onerror = function(event) {
      console.log("Why didn't you allow my web app to use IndexedDB?!");
    };
    request.onsuccess = function(event) {
      db = event.target.result;
    };
    

    拿到db对象之后,我们可以设置全局的异常处理:

    db.onerror = function(event) {
      // Generic error handler for all errors targeted at this database's
      // requests!
      console.error("Database error: " + event.target.errorCode);
    };
    

    IndexedDB中的table叫做object stores,和关系型数据库中的table一样,object stores中的每一个对象都和一个key相关联,和key相关的有两个概念 key path 和 key generator.

    如果存储的是javascript Object对象,那么可以指定该对象中的某一个属性作为key path,那么这个属性将会被作为key。

    如果没有指定key path,那么存储的Object可以是任何对象,甚至是基础类型比如数字和String。

    而key generator就是key的生成器。

    假如我们想要存储这样的数据:

    // This is what our customer data looks like.
    const customerData = [
      { ssn: "444-44-4444", name: "Bill", age: 35, email: "bill@company.com" },
      { ssn: "555-55-5555", name: "Donna", age: 32, email: "donna@home.org" }
    ];
    

    看一下对应的数据库操作是怎么样的:

    const dbName = "the_name";
    
    var request = indexedDB.open(dbName, 2);
    
    request.onerror = function(event) {
      // Handle errors.
    };
    request.onupgradeneeded = function(event) {
      var db = event.target.result;
    
      // Create an objectStore to hold information about our customers. We're
      // going to use "ssn" as our key path because it's guaranteed to be
      // unique - or at least that's what I was told during the kickoff meeting.
      var objectStore = db.createObjectStore("customers", { keyPath: "ssn" });
    
      // Create an index to search customers by name. We may have duplicates
      // so we can't use a unique index.
      objectStore.createIndex("name", "name", { unique: false });
    
      // Create an index to search customers by email. We want to ensure that
      // no two customers have the same email, so use a unique index.
      objectStore.createIndex("email", "email", { unique: true });
    
      // Use transaction oncomplete to make sure the objectStore creation is 
      // finished before adding data into it.
      objectStore.transaction.oncomplete = function(event) {
        // Store values in the newly created objectStore.
        var customerObjectStore = db.transaction("customers", "readwrite").objectStore("customers");
        customerData.forEach(function(customer) {
          customerObjectStore.add(customer);
        });
      };
    };
    

    我们需要在onupgradeneeded事件中处理所有的schema相关的操作。

    首先使用db.createObjectStore创建了一个customers的ObjectStore,并且使用了对象的keypath作为key。

    除了key之外,我们创建了两个index,以提高查询速度。

    最后我们监听transaction.oncomplete事件,并在里面加入存储object的操作。

    上面的代码中,我们使用了keyPath作为key。

    下面是一个使用key Generator的例子:

     var objStore = db.createObjectStore("names", { autoIncrement : true });
    

    indexdb中的CURD

    indexedDB的所有操作都需要在事务中,我们看一个开启事务的操作:

    var transaction = db.transaction(["customers"], "readwrite");
    

    上面的例子中使用readwrite来操作customers ObjectStore。

    transaction接收两个参数,第一个参数是一个数组,数组中是这个trans中将会处理的ObjectStores,第二个参数是处理的模式。

    有了transaction之后,我们可以监听事务的complete和error操作,然后就可以进行add操作了:

    // Do something when all the data is added to the database.
    transaction.oncomplete = function(event) {
      console.log("All done!");
    };
    
    transaction.onerror = function(event) {
      // Don't forget to handle errors!
    };
    
    var objectStore = transaction.objectStore("customers");
    customerData.forEach(function(customer) {
      var request = objectStore.add(customer);
      request.onsuccess = function(event) {
        // event.target.result === customer.ssn;
      };
    });
    

    上面的例子中,我们使用了add方法,add的前提是数据库中并不存在相同key的对象。除了add方法之外,我们还可以使用put方法,put方法主要用来进行更新操作。

    再看一个删除的操作:

    var request = db.transaction(["customers"], "readwrite")
                    .objectStore("customers")
                    .delete("444-44-4444");
    request.onsuccess = function(event) {
      // It's gone!
    };
    

    现在我们的数据库已经有了数据,我们看下怎么进行查询:

    var transaction = db.transaction(["customers"]);
    var objectStore = transaction.objectStore("customers");
    var request = objectStore.get("444-44-4444");
    request.onerror = function(event) {
      // Handle errors!
    };
    request.onsuccess = function(event) {
      // Do something with the request.result!
      console.log("Name for SSN 444-44-4444 is " + request.result.name);
    

    这里,我们直接使用了db.transaction,默认情况下是readonly模式的。

    下面是一个更新的例子:

    var objectStore = db.transaction(["customers"], "readwrite").objectStore("customers");
    var request = objectStore.get("444-44-4444");
    request.onerror = function(event) {
      // Handle errors!
    };
    request.onsuccess = function(event) {
      // Get the old value that we want to update
      var data = event.target.result;
      
      // update the value(s) in the object that you want to change
      data.age = 42;
    
      // Put this updated object back into the database.
      var requestUpdate = objectStore.put(data);
       requestUpdate.onerror = function(event) {
         // Do something with the error
       };
       requestUpdate.onsuccess = function(event) {
         // Success - the data is updated!
       };
    };
    

    更新我们使用的是put方法。

    使用游标cursor

    indexedDB支持游标操作,我们可以使用cursor来遍历objectStore的数据:

    var objectStore = db.transaction("customers").objectStore("customers");
    
    objectStore.openCursor().onsuccess = function(event) {
      var cursor = event.target.result;
      if (cursor) {
        console.log("Name for SSN " + cursor.key + " is " + cursor.value.name);
        cursor.continue();
      }
      else {
        console.log("No more entries!");
      }
    };
    

    openCursor可以接受多个参数,第一个参数可以接受key的查询范围,第二个参数用来指定遍历的方向。如果两个参数都为空的话,默认是所有的数据的以升序的顺序遍历。

    如果想遍历下一个游标,则可以调用cursor.continue。

    我们看一下两个参数的游标使用:

    // Only match "Donna"
    var singleKeyRange = IDBKeyRange.only("Donna");
    
    // Match anything past "Bill", including "Bill"
    var lowerBoundKeyRange = IDBKeyRange.lowerBound("Bill");
    
    // Match anything past "Bill", but don't include "Bill"
    var lowerBoundOpenKeyRange = IDBKeyRange.lowerBound("Bill", true);
    
    // Match anything up to, but not including, "Donna"
    var upperBoundOpenKeyRange = IDBKeyRange.upperBound("Donna", true);
    
    // Match anything between "Bill" and "Donna", but not including "Donna"
    var boundKeyRange = IDBKeyRange.bound("Bill", "Donna", false, true);
    
    // To use one of the key ranges, pass it in as the first argument of openCursor()/openKeyCursor()
    index.openCursor(boundKeyRange, "prev").onsuccess = function(event) {
      var cursor = event.target.result;
      if (cursor) {
        // Do something with the matches.
        cursor.continue();
      }
    };
    

    除了openCursor,我们还可以通过使用openKeyCursor来遍历KeyCursor:

    // Using a normal cursor to grab whole customer record objects
    index.openCursor().onsuccess = function(event) {
      var cursor = event.target.result;
      if (cursor) {
        // cursor.key is a name, like "Bill", and cursor.value is the whole object.
        console.log("Name: " + cursor.key + ", SSN: " + cursor.value.ssn + ", email: " + cursor.value.email);
        cursor.continue();
      }
    };
    
    // Using a key cursor to grab customer record object keys
    index.openKeyCursor().onsuccess = function(event) {
      var cursor = event.target.result;
      if (cursor) {
        // cursor.key is a name, like "Bill", and cursor.value is the SSN.
        // No way to directly get the rest of the stored object.
        console.log("Name: " + cursor.key + ", SSN: " + cursor.primaryKey);
        cursor.continue();
      }
    };
    

    除此之外,我们还可以直接通过index来进行查询:

    var index = objectStore.index("name");
    
    index.get("Donna").onsuccess = function(event) {
      console.log("Donna's SSN is " + event.target.result.ssn);
    };
    

    要使用index的前提就是需要在request.onupgradeneeded中创建index。

    本文作者:flydean程序那些事

    本文链接:http://www.flydean.com/indexeddb-kickoff/

    本文来源:flydean的博客

    欢迎关注我的公众号:「程序那些事」最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现!

    展开全文
  • 中国城市 db文件

    2015-06-10 16:04:08
    中国城市 db文件,可以用到android端的数据库
  • sqlcipher-3.0.1-windows含使用教程,可以直接加密db文件,直接解密db文件,直接查看数据库表数据。windows可用!含使用教程!自己用过整理的,很好用,所以2分不亏!
  • 使用db_bench 对rocksdb进行性能压测

    千次阅读 2020-05-30 16:59:16
    rocksdb提供benchmark工具来对自身性能进行全方位各个纬度的评估,包括顺序读写,随机读写,热点读写,删除,合并,查找,校验等性能的评估,十分好用。 工具编译 这里使用的是cmake的方式,主要是为了在自己用户下...


    rocksdb提供benchmark工具来对自身性能进行全方位各个纬度的评估,包括顺序读写,随机读写,热点读写,删除,合并,查找,校验等性能的评估,十分好用。

    1. 工具编译

    这里使用的是cmake的方式,主要是为了在自己用户下指定对应的第三方库的路径(glfags等)以及指定是否开启rocksdb自己的压缩算法编译,否则直接make 原生的Makefile问题较多且 db_bench所依赖的一些库都没法自动链接进去(zstd,snappy等压缩算法 默认是不编译到db_bench中的)

    如果你的db_bench工具已经安装好了,可以跳过当前步骤,如果没有编译好,不想这么麻烦,可以直接看下面,会提供一个整体的便捷编译脚本。

    基本流程如下:

    1. 下载rocksdb源码
      git clone https://github.com/facebook/rocksdb.git
      
      如果需要指定对应的版本,可以下载好之后执行
      git branch xxx切换到对应版本的分支
    2. 第三方库的编译安装
      a. gflags
      a. git clone https://github.com/gflags/gflags.git
      b. cd gflags
      c. mkdir build && cd build
      
      #以下DCMAKE_INSTALL_PREFIX 之后的路径为自己想要安装的路径,如果有root权限且可以安装到系统目录下,那么可以不用指定prefix选项,BUILD_SHARED_LIBS选项表示开启编译gflags的动态库,否则默认不编译动态库
      d. cmake .. -DCMAKE_INSTALL_PREFIX=/xxx -DBUILD_SHARED_LIBS=1 -DCMAKE_BUILD_TYPE=Release 
      
      e. make && make install	
      
      #增加gflags的include 和 lib库的路径到系统库下面,如上面未指定路径,则系统默认安装在
      #/usr/local/gflags
      f. 编辑当前用户下的bashrc,添加如下内容:
      export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/xxx/gcc-5.3/lib64:/xxx/gflags/lib
      export LIBRARY_PATH=$LIBRARY_PATH:/xxx/gflags/include
      
      b. 安装snappy
      sudo yum install snappy snappy-devel
      c. 安装 zlib
      yum install zlib zlib-devel
      d. 安装 bzip2
      yum install bzip2 bzip2-devel
      e.安装lz4
      yum install lz4-devel
      f. 安装zstardard
      wget https://github.com/facebook/zstd/archive/v1.1.3.tar.gz
      mv v1.1.3.tar.gz zstd-1.1.3.tar.gz
      tar zxvf zstd-1.1.3.tar.gz
      cd zstd-1.1.3
      make && sudo make install
      
    3. 生成makefile
      cd rocksdb && mkdir build
      
      #以下的prefix路径需要指定安装gflags的prefix路径,否则编译过程中无法链接到gflags的库
      #如果cmake 版本过低,使用cmake3
      #DWITH_xxx 表示开启几个压缩算法的编译选项,否则运行db_bench时rocksdb产生数据压缩的时候无法找到对应的库
      cmake .. -DCMAKE_PREFIX_PATH=/xxx -DWITH_SNAPPY=1 -DWITH_LZ4=1 -DWITH_ZLIB=1 -DWITH_ZSTD=1 -DCMAKE_BUILD_TYPE=Release=release
      
    4. 编译
      以上会通过上级目录的CMakeList.txt 在当前目录生成Makefile,最终执行编译
      make -j
      

    成功后db_bench工具会在当前目录下生成。
    编译脚本如下,那一些压缩算法的lib还是需要提前装好的。

    #!/bin/sh
    
    set -x
    
    # build gflags
    function build_gflags()
    {
      local source_dir
      local build_dir
    
      # dir is exists, there is no need to clone again
      if [ -e "gflags" ] && [ -e "gflags/build" ]; then
        return
      fi
    
      git clone  https://github.com/gflags/gflags.git
      if [ $? -ne 0 ]; then
        echo "git clone gflags failed."
      fi
    
      cd gflags
    
      source_dir=$(pwd)
      build_dir=$source_dir/build
    
      mkdir -p "$build_dir"/ \
        && cd "$build_dir"/ \
        && cmake3 .. -DCMAKE_INSTALL_PREFIX="$build_dir" -DBUILD_SHARED_LIBS=1 -DBUILD_STATIC_LIBS=1 \
        && make \
        && make install \
        && cd ../../
    }
    
    git submodule update --init --recursive
    build_gflags
    
    SOURCE_DIR=$(pwd)
    
    BUILD_DIR="$SOURCE_DIR"/build
    GFLAGS_DIR=gflags/build
    
    # for using multi cores parallel compile
    NUM_CPU_CORES=$(grep "processor" -c /proc/cpuinfo)
    if [ -z "${NUM_CPU_CORES}" ] || [ "${NUM_CPU_CORES}" = "0" ] ; then
        NUM_CPU_CORES=1
    fi
    
    mkdir -p "$BUILD_DIR"/ \
      && cd "$BUILD_DIR"
      
    cmake3 "$SOURCE_DIR" -DCMAKE_BUILD_TYPE=Release -DWITH_SNAPPY=ON -DWITH_TESTS=OFF -DCMAKE_PREFIX_PATH=$GFLAGS_DIR
    make -j $NUM_CPU_CORES
    

    2. 基本性能压测

    由于db_bench工具的选项太多了,这里直接提取社区的测试方式
    核心是benchmark,它代表本次测试使用的压测方式,benchmark的列表如下

    fillseq       -- write N values in sequential key order in async mode
    fillseqdeterministic       -- write N values in the specified key order and keep the shape of the LSM tree
    fillrandom    -- write N values in random key order in async mode
    filluniquerandomdeterministic       -- write N values in a random key order and keep the shape of the LSM tree
    overwrite     -- overwrite N values in random key order in async mode
    fillsync      -- write N/100 values in random key order in sync mode
    fill100K      -- write N/1000 100K values in random order in async mode
    deleteseq     -- delete N keys in sequential order
    deleterandom  -- delete N keys in random order
    readseq       -- read N times sequentially
    readtocache   -- 1 thread reading database sequentially
    readreverse   -- read N times in reverse order
    readrandom    -- read N times in random order
    readmissing   -- read N missing keys in random order
    readwhilewriting      -- 1 writer, N threads doing random reads
    readwhilemerging      -- 1 merger, N threads doing random reads
    readrandomwriterandom -- N threads doing random-read, random-write
    prefixscanrandom      -- prefix scan N times in random order
    updaterandom  -- N threads doing read-modify-write for random keys
    appendrandom  -- N threads doing read-modify-write with growing values
    mergerandom   -- same as updaterandom/appendrandom using merge operator. Must be used with merge_operator
    readrandommergerandom -- perform N random read-or-merge operations. Must be used with merge_operator
    newiterator   -- repeated iterator creation
    seekrandom    -- N random seeks, call Next seek_nexts times per seek
    seekrandomwhilewriting -- seekrandom and 1 thread doing overwrite
    seekrandomwhilemerging -- seekrandom and 1 thread doing merge
    crc32c        -- repeated crc32c of 4K of data
    xxhash        -- repeated xxHash of 4K of data
    acquireload   -- load N*1000 times
    fillseekseq   -- write N values in sequential key, then read them by seeking to each key
    randomtransaction     -- execute N random transactions and verify correctness
    randomreplacekeys     -- randomly replaces N keys by deleting the old version and putting the new version
    timeseries            -- 1 writer generates time series data and multiple readers doing random reads on id
    
    • 创建一个db,并写入一些数据 ./db_bench --benchmarks="fillseq"
      但是这样并不会打印更多有效的元信息

      DB path: [/tmp/rocksdbtest-1001/dbbench]
      fillseq      :       2.354 micros/op 424867 ops/sec;   47.0 MB/s
      
    • 创建一个db,并打印一些元信息./db_bench --benchmarks="fillseq,stats"
      --benchmarks表示测试的顺序,支持持续叠加。本次就是顺序写之后打印db的状态信息。
      这样会打印db相关的stats信息,包括db的stat信息和compaction的stat信息

      DB path: [/tmp/rocksdbtest-1001/dbbench]
      # 测试顺序写的性能信息
      fillseq      :       2.311 micros/op 432751 ops/sec;   47.9 MB/s
      
      
      ** Compaction Stats [default] **
      Level    Files   Size     Score Read(GB)  Rn(GB) Rnp1(GB) Write(GB) Wnew(GB) Moved(GB) W-Amp Rd(MB/s) Wr(MB/s) Comp(sec) CompMergeCPU(sec) Comp(cnt) Avg(sec) KeyIn KeyDrop
      ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
        L0      1/0   28.88 MB   0.2      0.0     0.0      0.0       0.0      0.0       0.0   1.0      0.0     60.6      0.48              0.31         1    0.477       0      0
       Sum      1/0   28.88 MB   0.0      0.0     0.0      0.0       0.0      0.0       0.0   1.0      0.0     60.6      0.48              0.31         1    0.477       0      0
       Int      0/0    0.00 KB   0.0      0.0     0.0      0.0       0.0      0.0       0.0   1.0      0.0     60.6      0.48              0.31         1    0.477       0      0
      
      ** Compaction Stats [default] **
      Priority    Files   Size     Score Read(GB)  Rn(GB) Rnp1(GB) Write(GB) Wnew(GB) Moved(GB) W-Amp Rd(MB/s) Wr(MB/s) Comp(sec) CompMergeCPU(sec) Comp(cnt) Avg(sec) KeyIn KeyDrop
      -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
      High      0/0    0.00 KB   0.0      0.0     0.0      0.0       0.0      0.0       0.0   0.0      0.0     60.6      0.48              0.31         1    0.477       0      0
      Uptime(secs): 2.3 total, 2.3 interval
      Flush(GB): cumulative 0.028, interval 0.028
      AddFile(GB): cumulative 0.000, interval 0.000
      AddFile(Total Files): cumulative 0, interval 0
      AddFile(L0 Files): cumulative 0, interval 0
      AddFile(Keys): cumulative 0, interval 0
      Cumulative compaction: 0.03 GB write, 12.34 MB/s write, 0.00 GB read, 0.00 MB/s read, 0.5 seconds
      Interval compaction: 0.03 GB write, 12.50 MB/s write, 0.00 GB read, 0.00 MB/s read, 0.5 seconds
      Stalls(count): 0 level0_slowdown, 0 level0_slowdown_with_compaction, 0 level0_numfiles, 0 level0_numfiles_with_compaction, 0 stop for pending_compaction_bytes, 0 slowdown for pending_compaction_bytes, 0 memtable_compaction, 0 memtable_slowdown, interval 0 total count
      
      ** File Read Latency Histogram By Level [default] **
      
      ** DB Stats **
      Uptime(secs): 2.3 total, 2.3 interval
      Cumulative writes: 1000K writes, 1000K keys, 1000K commit groups, 1.0 writes per commit group, ingest: 0.12 GB, 53.39 MB/s
      Cumulative WAL: 1000K writes, 0 syncs, 1000000.00 writes per sync, written: 0.12 GB, 53.39 MB/s
      Cumulative stall: 00:00:0.000 H:M:S, 0.0 percent
      Interval writes: 1000K writes, 1000K keys, 1000K commit groups, 1.0 writes per commit group, ingest: 124.93 MB, 54.06 MB/s
      Interval WAL: 1000K writes, 0 syncs, 1000000.00 writes per sync, written: 0.12 MB, 54.06 MB/s
      Interval stall: 00:00:0.000 H:M:S, 0.0 percent
      

      更多的meta operation操作如下

      • compact 对整个数据库进行合并
      • stats 打印db的状态信息
      • resetstats 重置db的状态信息
      • levelstats 打印每一层的文件个数以及每一层的占用的空间大小
      • sstables 打印sst文件的信息

      对应的sstables和levelstats显示信息如下

      --- level 0 --- version# 2 ---
       7:30286882[1 .. 448148]['00000000000000003030303030303030' \
       seq:1, type:1 .. '000000000006D6933030303030303030' seq:448148, type:1](0)
      --- level 1 --- version# 2 ---
      --- level 2 --- version# 2 ---
      --- level 3 --- version# 2 ---
      --- level 4 --- version# 2 ---
      --- level 5 --- version# 2 ---
      --- level 6 --- version# 2 ---
      
      
      Level Files Size(MB)
      --------------------
        0        1       29
        1        0        0
        2        0        0
        3        0        0
        4        0        0
        5        0        0
        6        0        0
      
    • 单独随机写测试
      相关的参数可以自己配置,这里仅仅列出一部分参数
      可以通过 ./db_bench --help自己查看想要的配置参数,当然配置前需要对各个参数有一定的了解。

      ./db_bench  \
      --benchmarks="fillrandom,stats,levelstats" \
      --enable_write_thread_adaptive_yield=false \
      --disable_auto_compactions=false \
      --max_background_compactions=32 \
      --max_background_flushes=4 \
      --write_buffer_size=536870912 \
      --min_write_buffer_number_to_merge=2 \
      --max_write_buffer_number=6 \
      --target_file_size_base=67108864 \
      --max_bytes_for_level_base=536870912 \
      --compression_type=none \ #关闭压缩
      --num=500000000 \ #总共写入的请求个数,如果达不到则写30秒就停止
      --duration=30 \ #持续IO的时间是30秒
      --threads=1000\ #并发1000个线程
      --value_size=8192\ #value size是8K
      --key_size=16 \ #key size 16B
      --enable_pipelined_write=true \
      --db=./db_bench_test \ #指定创建db的目录
      --wal_dir=./db_bench_test \ #指定创建wal的目录
      --allow_concurrent_memtable_write=true \ #允许并发写memtable
      --disable_wal=false \
      --batch_size=1 \
      --sync=false \ #是否开启sync
      

      在这个workload下,每一次benchmark db_bench都会重新创建db,可能是遗留原因。而有的时候,我们想要在原有db之前追加一定条目的请求,并不希望之前的db被清理掉。可以这样简单更改一下db_bench的代码:
      我们使用fillrandom workload的时候,搭配use_existing_db=1 默认会退出
      在这里插入图片描述
      这个时候我们只需要将,fillrandom workload下的fresh_db 更改为false就可以继续测试了,每一次fillrandom都会在之前的基础上增加条目,而不会destory之前的db。
      在这里插入图片描述

    • 随机读
      使用之前fillrandom创建的db,进行随机读取,需要开启use_existing_keys=1use_existing_db=1,否则都会是not-found,被bloom-filter过滤,不会命中之前写入的数据。

      ./db_bench \
      --benchmarks="fillseq,stats,readrandom,stats"
      --enable_write_thread_adaptive_yield=false \
      --disable_auto_compactions=false \
      --max_background_compactions=32 \
      --max_background_flushes=4 \
      --write_buffer_size=536870912 \
      --min_write_buffer_number_to_merge=2 \
      --max_write_buffer_number=6 \
      --target_file_size_base=67108864 \
      --max_bytes_for_level_base=536870912 \
      --use_existing_keys=1 \ #建议使用已存在key进行读,否则就一直被filter过滤掉,打不到磁盘,测试不精确
      --use_existing_db=1 \
      --cache_size=2147483648 \ #2G的block-cache,默认是8M,实际生产环境,如果read-heavy应该设置为内存大小的三分之一。
      --num=500000000 \ #总共写入的请求个数,如果达不到则写30秒就停止
      --duration=30 \ #持续IO的时间是30秒
      --threads=1000 \ #并发1000个线程
      --value_size=8192 \ #value size是8K
      --key_size=16 \ #key size 16B
      --enable_pipelined_write=true \
      --db=./db_bench_test \ #指定创建db的目录
      --wal_dir=./db_bench_test \ #指定创建wal的目录
      --allow_concurrent_memtable_write=true \ #允许并发写memtable
      --disable_wal=false \	
      

      如果要测试热点读,可以指定参数--key_id_range=100000,表示生成的key的范围是在100000范围内,该测试需要在benchmark中增加timeseries

    • 读写混合readwhilewriting
      9个线程读,一个线程写

      ./db_bench \
      --benchmarks="readwhilewriting,stats"
      --enable_write_thread_adaptive_yield=false \
      --disable_auto_compactions=false \
      --max_background_compactions=32 \
      --max_background_flushes=4 \
      --write_buffer_size=536870912 \
      --min_write_buffer_number_to_merge=2 \
      --max_write_buffer_number=6 \
      --target_file_size_base=67108864 \
      --max_bytes_for_level_base=536870912 \
      --use_existing_keys=1 \ #建议使用已存在key进行读,否则就一直被filter过滤掉,打不到磁盘,测试不精确
      --use_existing_db=1 \
      --cache_size=2147483648 \ #2G的block-cache,默认是8M,实际生产环境,如果read-heavy应该设置为内存大小的三分之一。
      --num=500000000 \ #总共写入的请求个数,如果达不到则写30秒就停止
      --duration=30 \ #持续IO的时间是30秒
      --threads=1000\ #并发1000个线程
      --value_size=8192\ #value size是8K
      --key_size=16 \ #key size 16B
      --enable_pipelined_write=true \
      --db=./db_bench_test \ #指定创建db的目录
      --wal_dir=./db_bench_test \ #指定创建wal的目录
      --allow_concurrent_memtable_write=true \ #允许并发写memtable
      --disable_wal=false \	
      
    • 随机读随机写 ReadRandomWriteRandom
      随机读一个请求,随机写一个请求,可以指定读写比,readwritepercent;默认是90%的读,可以降低读的比例
      需要注意开启--use_existing_keys=1--use_existing_db=1

      ./db_bench \
      --benchmarks="readrandomwriterandom,stats"
      --enable_write_thread_adaptive_yield=false \
      --disable_auto_compactions=false \
      --max_background_compactions=32 \
      --max_background_flushes=4 \
      --write_buffer_size=536870912 \
      --min_write_buffer_number_to_merge=2 \
      --max_write_buffer_number=6 \
      --target_file_size_base=67108864 \
      --max_bytes_for_level_base=536870912 \
      --use_existing_keys=1 \ #建议使用已存在key进行读,否则就一直被filter过滤掉,打不到磁盘,测试不精确
      --use_existing_db=1 \ #建议打开,使用已经存在的db
      --cache_size=2147483648 \ #2G的block-cache,默认是8M,实际生产环境,如果read-heavy应该设置为内存大小的三分之一。
      --readwritepercent=50 \ #指定读写比 1:1,一次随机读,对应一次随机写
      --num=500000000 \ #总共写入的请求个数,如果达不到则写30秒就停止
      --duration=30 \ #持续IO的时间是30秒
      --threads=1000\ #并发1000个线程
      --value_size=8192\ #value size是8K
      --key_size=16 \ #key size 16B
      --enable_pipelined_write=true \
      --db=./db_bench_test \ #指定创建db的目录
      --wal_dir=./db_bench_test \ #指定创建wal的目录
      --allow_concurrent_memtable_write=true \ #允许并发写memtable
      --disable_wal=false \	
      

    3. 便捷Benchmark.sh 自动匹配workload

    ps: 需要注意的是benchmark.sh 中很多参数并不是默认的,而是官方给的一些适配当前benchmark workload 的系列优化之后的参数,所以如果大家想要测试自己的option,这个方法并不推荐,还是使用上面的db_bench方式来测试。

    因为db_bench选项太多,而测试纬度很难做到统一(可能一个memtable大小的配置都会导致测试出来的写性能相关的的数据差异很大),所以官方给出了一个benchmark.sh脚本用来对各个workload进行测试。
    该脚本能够将db_bench测试结果中的stats信息进行统计汇总打印(qps,),更放方便查看。

    这个测试需要将编译好的db_bench二进制文件和./tools/benchmark.sh放到同一个目录下即可,测试项可以参考官方给出的workload,Performance Benchmarks

    • 随机插入 bulkload,制造好数据集
      这里的随机插入是指单纯的随机写,且禁掉自动compaction,将当前请求插入完成之后会再进行手动compaction
      NUM_KEYS=900000000 NUM_THREADS=32 CACHE_SIZE=6442450944 benchmark.sh bulkload
      总体来说这个随机插入结果相比于默认配置是偏高的,benchmark.sh中的脚本对memtable相关的配置如下:
      在这里插入图片描述
      很明显性能肯定好于默认配置,好处是官方有一个在指定硬件之下的workload测试结果,可以进行对比参考。

    • 随机写,覆盖写
      在上一次已有的数据基础上进行测试,会覆盖写9亿条key
      NUM_KEYS=900000000 NUM_THREADS=32 CACHE_SIZE=6442450944 DURATION=5400 benchmark.sh overwrite

    • 读时写,9个线程读,一个线程写
      这里的读是从已经存在的key中进行读
      NUM_KEYS=900000000 NUM_THREADS=32 CACHE_SIZE=6442450944 DURATION=5400 benchmark.sh readwhilewriting

    • 随机读
      NUM_KEYS=900000000 NUM_THREADS=32 CACHE_SIZE=6442450944 DURATION=5400 benchmark.sh readrandom

    4. 上限的benchmark及参数

    欢迎大家补充各自的上限 workload 。

    4.1 随机写

    单进程 32个线程,32个db,各自的写吞吐会以秒计形态输出到一个report.csv。这里线程数 和 db数可以根据自己环境的cpu核心情况而定,基本不用担心write-stall问题。

     ./db_bench \
       --benchmarks=fillrandom,stats \
       --readwritepercent=90 \
       --num=3000000000 \
       --threads=32 \
       --db=./db \
       --wal_dir=./db \
       --duration=3600 \
       -report_interval_seconds=1 \
       --key_size=16 \
       --value_size=128 \
       --max_write_buffer_number=16 \
       -max_background_compactions=32 \
       -max_background_flushes=16 \
       -subcompactions=8 \
       -num_multi_db=32 \
       -compression_type=none 
    

    如果想要支持 direct_io 写,可以打开
    --use_direct_io_for_flush_and_compaction=true,这个配置是在写sst时 也就是flush & compaction 生效。
    如果想要测试 mmap 写,则可以打开
    --mmap_write=true

    4.2 完全随机读

    随机读想要命中所有的key,需要打开 use_existing_db=1use_existing_keys=1
    需要注意的是 use_existing_keys 开启之后不能直接读多db,只能读单个db,因为它会在真正执行读workload 之前从这一个db内scan 所有的key 到一个数组中,同时 配置的 --num 选项是失效的,这里会填充扫描上来的key的个数。
    使用这个配置之后 worklaod 不会立即启动,会卡一会扫描完所有的key之后才真正开始随机读(读的过程是生成随机下标来进行访问)。
    在这里插入图片描述
    这个测试是使用默认大小的block_cache (8MB),以及 开启bloom filter,因为我们是use_existing_keys,那bloom filter基本没什么用。

     $DB_BENCH \
       --benchmarks=readrandom,stats \
       --num=3000000000 \
       --threads=40 \
       --db=./db \
       --wal_dir=./db \
       --duration="$DURATION" \
       --statistics \
       -report_interval_seconds=1 \
       --key_size=16 \
       --value_size=128 \
       -use_existing_db=1 \
       -use_existing_keys=1 \
       -compression_type=none \
    

    想要测试 direct 读,添加-use_direct_reads=true,那么读就不会用os pagecache了,这里可以搭配-cache_size=1073741824 以及其他block_cache的配置进行测试,来看rocksdb的block_cache 相比于os pagecache的收益。

    想要测试 mmap 读,添加-mmap_read=true 即可。

    4.3 热点读

    这里基本是使用之前的配置,主要是增加一个数据倾斜的配置 read_random_exp_range,它会用来产生倾斜的随机下标。
    在这里插入图片描述
    这个值越大,下标的倾斜越严重(可以理解为key-range 越小)。

     $DB_BENCH \
       --benchmarks=readrandom,stats \
       --num=3000000000 \
       --threads=40 \
       --db=./db \
       --wal_dir=./db \
       --duration="$DURATION" \
       --statistics \
       -report_interval_seconds=1 \
       --key_size=16 \
       --value_size=128 \
       -use_existing_db=1 \
       -use_existing_keys=1 \
       -compression_type=none \
       -read_random_exp_range=0.8 \
    

    以上所有的workload 最后的结果
    可以通过 tail -f report.csv 查看 吞吐

    secs_elapsed,interval_qps
    1,3236083
    2,2877314
    3,2645623
    4,2581939
    5,2655481
    6,2038635
    7,2226018
    8,2366941
    ...
    

    后面可以通过python 绘图脚本系列简单记录进行曲线绘图。

    展开全文
  • 使用Altium designer软件绘制DB接口封装图如下所示: 具体获取方式见文末链接 (1)DB9针 (2)DB15针 (3)DB25针 (4)DB37针 (5)DB50针 AD封装库链接: 链接:...

    使用Altium designer软件绘制DB接口封装图如下所示:

    具体获取方式见文末链接

    (1)DB9针

    在这里插入图片描述

    (2)DB15针

    在这里插入图片描述

    (3)DB25针

    在这里插入图片描述

    (4)DB37针

    在这里插入图片描述

    (5)DB50针

    在这里插入图片描述

    AD封装库链接:

    链接:https://pan.baidu.com/s/1zyPuIC4qhpzHNwulYk9yXw
    提取码:gexy

    展开全文
  • DB数据库编辑器(破解版)_3.1.6.54

    热门讨论 2014-07-03 21:14:55
    DB数据库编辑器(破解版)_3.1.6.54
  • dB的相关概念及计算

    千次阅读 2021-03-15 13:02:56
    dB的相关概念及计算 我们在平常工作中经验遇到dB、dBm、DBi和dBd,我也经常会搞错,所以今天我们来系统的学习一下他们各自的计算及概念,加深一下印象,欢迎各位大神指导,希望对新手有用。 一、 dB概念及算法 1、...
  • db换算(db和功率的换算)

    千次阅读 2021-01-26 11:53:53
    DB是一个比值,是一个数值,是一个纯计数方法,没有任何...以功率为例:信号功率为X = 100000W = 10^5 基准功率为Y=1W dB的值:Lx(dB) = 10*lg(10^5W/1W) dB= 10*lg(10^5) dB= 50 dB 同理:X = 10^-15 Lx(dB) = 10...
  • db与w换算(1db等于多少功率)

    千次阅读 2021-01-26 11:53:53
    dBm是功率的单位,1dbm等于1毫瓦,也就是千分之一瓦。 1、 dBm这是我们接触到....dB的意义其实再简单不过了,就是把一个很大(后面跟一长串0的.DB是一个比值,是一个数值,是一个纯计数方法,没有...
  • 功率和db换算(功率与db换算表)

    千次阅读 2021-02-06 10:42:02
    dBm是功率的单位,1dbm等于1毫瓦,也就是千分之一瓦。 1、 dBm这是我们接触到比较多的一个单位,也是唯一一...dB的意义其实再简单不过了,就是把一个很大(后面跟一长串0的.DB是一个比值,是一个数值,是一个纯计数方...
  • OleDb驱动程序

    热门讨论 2012-09-04 23:54:41
    OleDb驱动程序
  • GaussDB系列数据库简介

    千次阅读 2020-08-07 10:45:56
    GaussDB目前支持TD、Natezza、Oracle、MySQL、DB2、sybase、PG的离线数据迁移, 支持Oracle的全量+增强的在线迁移。 GaussDB版本的区别: GaussDB T(OLTP): 前身是GauussDB 100, 主打OLTP在线事务处理。 用于存储...
  • dB(分贝)定义及其应用

    万次阅读 2020-11-30 15:17:26
    目录 1.1 dB的诞生背景 1.2 dB的定义 ...而关于dB的讨论也是一个历久常新的话题,因为每一位从业者都会经历一个“搞懂dB是什么”的阶段,尤其是在声学领域,dB经常用作为表征声压级SPL(Sound Pressure
  • TimescaleDB部署

    千次阅读 2018-12-03 17:35:23
    1、准备 ...Timescale: timescaledb(只支持pgsql9.x和10.x) Timescale release_tag: 1.0.0 cmake: cmake-3.10.2.tar(Timescale要求CMake 3.4或更高版本) 安装TimescaleDB时序数据库需要...
  • 本文介绍RocksDB的一些基本概念和术语,及Java程序如何使用RocksDB
  • 通信领域的dB计量单位

    千次阅读 2021-01-07 09:20:16
    在通信技领域,尤其是射频领域,常常碰到dB开头的计量单位,如dBm,dBi,dBc,dBr等等,初学时容易迷糊。这里做一个小结。 dB 首先说说dB的概念。dB是英文单词decible的缩写,译作是分贝;英文还有个单词bel,也...
  • RocksDB简介

    万次阅读 2019-10-07 18:04:49
    RocksDB是FaceBook起初作为实验性质开发的,旨在充分实现快存上存储数据的服务能力。由Facebook的Dhruba Borthakur于2012年4月创建的LevelDB的分支,最初的目标是提高服务工作负载的性能,最大限度的发挥闪存和RAM的...
  • BerkeleyDB库简介

    千次阅读 2019-02-22 19:29:02
    BerkeleyDB(简称为BDB)是一种以key-value为结构的嵌入式数据库引擎: 嵌入式:bdb提供了一系列应用程序接口(API),调用这些接口很简单,应用程序和bdb所提供的库一起编译/链接成为可执行程序; NOSQL:bdb不...
  • 文章目录初始GaussDBGaussDB的版本GaussDB版本的区别OLTP和OLAP比较GaussDB T介绍GaussDB A 介绍MPP架构介绍架构组件介绍 初始GaussDB 名字的由来:GaussDB是华为数据库产品品牌名,致敬数据加高斯(Gauss) GaussDB...
  • dB 数值范围根据实际测量的参考值有变化。计算能量: 计算场量: 领域 电压 dBu/dBv dBmV dB(1 mVRMS)–电压相对于75 Ω阻抗上的1毫伏。[16]广泛用于有线电视网,其接收端的单路电视信号强度名义为0 dBmV。...
  • Microsoft.ACE.OLEDB.12.0

    千次下载 热门讨论 2012-05-17 15:10:24
    解决 未在本地计算机上注册“Microsoft.ACE.OLEDB.12.0”提供程序。的问题
  • navicat导入db文件_db文件转换为txt

    千次阅读 2020-12-22 18:24:33
    但是对于新手来说(比如说我),Navicat for MySQL 里的导出连接、运行SQL文件、导入向导、还原备份、这些 关键是要弄清楚.db是什么弄明白就好了,用odbc连接.db,然后用navicat的导入导出功能进行数据导入处理。...
  • DB数据库文件查看器

    千次下载 热门讨论 2011-10-12 15:24:37
    绿色 小巧 的DB数据库文件查看器,可以查看和修改DB文件。
  • 声音单位dB理解

    千次阅读 2021-06-04 17:26:11
    声音单位dB理解 0、前言 SPL:Sound Presure Level,即声压级。 0.1 有效值(RMS:Root Mean Square,均方根) 正弦信号峰值和有效值换算公式: 其中Up为峰值, 0.2 对数相关计算公式 lgA - lgB = lg(A/B) lgA + ...
  • dB的换算

    万次阅读 2020-09-12 13:38:02
    dB的意义 1.        dB基本上是一个比例数值,也就是一种倍数的表示单位。也就是 测试数据 与 参考标准的相对差异表示。   2.      &...
  • 这里以官方的Microsoft SQL Server 2012 Express LocalDB加以说明,VS从2012开始应该都集成了此功能。 Microsoft SQL Server 2012 Express LocalDB 是面向程序开发人员的 SQL Server Express 的执行模式。 LocalDB ...
  • 图数据库 OrientDB 安装 及 初步使用

    千次阅读 2018-08-07 21:56:18
    图数据库 OrientDB 安装 及 初步使用
  • 西门子db数据块详解

    万次阅读 2020-12-28 22:39:38
    西门子PLC从300/400系列开始STEP7软件引入了DB块的概念,DB就是数据块,这个DB区有点象西门子200PLC中的V变量数据区,200中编程使用V区的点,300中就可以使用DB区来存储数据,以及触摸屏上位机这些的通讯也都主要...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,411,652
精华内容 964,660
关键字:

db