Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Rails 5 Mysql UUID

Câu trả lời của tôi là bản cập nhật câu trả lời của @ santosh. Tôi đang kết hợp tất cả các phương pháp hay nhất được mô tả ở đây:

Tôi đang sử dụng simple_uuid đá quý vì nó có thể tạo UUID "v1". Tích hợp sẵn SecureRandom.uuid của Ruby tạo v4. Chúng ta cần v1, vì đó là thứ kết hợp dấu thời gian như một phần của UUID. Đọc các liên kết ở trên để hiểu sâu hơn. UUID() của MySQL hàm tạo UUID v1.

ứng dụng / mô hình / mối quan tâm / binary_uuid_pk.rb

module BinaryUuidPk
  extend ActiveSupport::Concern

  included do
    before_validation :set_id, on: :create
    validates :id, presence: true
  end

  def set_id
    uuid_object = SimpleUUID::UUID.new
    uuid_string = ApplicationRecord.rearrange_time_of_uuid( uuid_object.to_guid )
    uuid_binary = ApplicationRecord.id_binary( uuid_string )
    self.id = uuid_binary
  end

  def uuid
    self[:uuid] || (id.present? ? ApplicationRecord.format_uuid_with_hyphens( id.unpack('H*').first ).upcase : nil)
  end


  module ClassMethods
    def format_uuid_with_hyphens( uuid_string_without_hyphens )
      uuid_string_without_hyphens.rjust(32, '0').gsub(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/, '\1-\2-\3-\4-\5')
    end

    def rearrange_time_of_uuid( uuid_string )
      uuid_string_without_hyphens = "#{uuid_string[14, 4]}#{uuid_string[9, 4]}#{uuid_string[0, 8]}#{uuid_string[19, 4]}#{uuid_string[24..-1]}"
      ApplicationRecord.format_uuid_with_hyphens( uuid_string_without_hyphens )
    end

    def id_binary( uuid_string )
      # Alternate way: Array(uuid_string.downcase.gsub(/[^a-f0-9]/, '')).pack('H*')
      SimpleUUID::UUID.new( uuid_string ).to_s
    end

    def id_str( uuid_binary_string )
      SimpleUUID::UUID.new( uuid_binary_string ).to_guid
    end

    # Support both binary and text as IDs
    def find( *ids )
      ids = [ids] unless ids.is_a?( Array )
      ids = ids.flatten

      array_binary_ids = ids.each_with_object( [] ) do |id, array|
        case id
          when Integer
            raise TypeError, 'Expecting only 36 character UUID strings as primary keys'
          else
            array <<  SimpleUUID::UUID.new( id ).to_s

        end
      end

      super( array_binary_ids )
    end
  end
end

app / models / application_record.rb

## ApplicationRecord (new parent of all models in Rails 5)
class ApplicationRecord < ActiveRecord::Base
  self.abstract_class = true

  include BinaryUuidPk
end

Giờ đây, tất cả các kiểu máy sẽ hỗ trợ khóa chính UUID được tối ưu hóa.

Di chuyển mẫu

class CreateUserProfiles < ActiveRecord::Migration[5.0]
  def change
    create_table :user_profiles, id: false do |t|
      t.binary :id, limit: 16, primary_key: true, null: false
      t.virtual :uuid, type: :string, limit: 36, as: "insert( insert( insert( insert( hex(id),9,0,'-' ), 14,0,'-' ), 19,0,'-' ), 24,0,'-' )"
      t.index :uuid, unique: true

      t.string :name, null: false
      t.string :gender, null: false
      t.date :date_of_birth
      t.timestamps null: false
    end

    execute <<-SQL
      CREATE TRIGGER before_insert_user_profiles
        BEFORE INSERT ON user_profiles
        FOR EACH ROW
        BEGIN
          IF new.id IS NULL THEN
            SET new.id = UUID_TO_BIN(uuid(), 1);
          END IF;
        END
    SQL
  end
end

Thêm UUID_TO_BIN() chức năng của MySQL DB :

DELIMITER //
CREATE FUNCTION UUID_TO_BIN(string_uuid BINARY(36), swap_flag INT)
        RETURNS BINARY(16)
        LANGUAGE SQL  DETERMINISTIC  CONTAINS SQL  SQL SECURITY INVOKER
      RETURN
        UNHEX(CONCAT(
            SUBSTR(string_uuid, 15, 4),
            SUBSTR(string_uuid, 10, 4),
            SUBSTR(string_uuid,  1, 8),
            SUBSTR(string_uuid, 20, 4),
            SUBSTR(string_uuid, 25) ));
//
DELIMITER ;

Hàm trên được tích hợp sẵn cho MySQL 8.0 trở lên. Tại thời điểm viết bài, 8.0 vẫn chưa phải là GA. Vì vậy, tôi đang thêm chức năng cho bây giờ. Nhưng tôi đã giữ chữ ký hàm giống như những gì có trong MySQL 8.0. Vì vậy, khi chúng tôi chuyển sang 8.0, tất cả các di chuyển và trình kích hoạt của chúng tôi sẽ vẫn hoạt động.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sao chép / đồng bộ hóa db Firebird cục bộ sang db trực tuyến

  2. Làm cách nào để bạn chỉnh sửa một thủ tục được lưu trữ trong MySQL?

  3. PHP / MySQL - Lưu trữ dữ liệu mảng dưới dạng JSON, thực tế không tốt?

  4. Kết nối SSL từ PHP đến MySQL

  5. Lỗi quá nhiều tệp mở trên Ubuntu 8.04