giải pháp tiêu chuẩn để lưu trữ các đơn vị đo lường


7

GIỚI THIỆU VÀ THÔNG TIN LIÊN QUAN:

Hãy để chúng tôi nói rằng tôi có một bảng lưu trữ chiều cao và cân nặng của một người, đại loại như thế này:

PersonTable < # ID int, Name varchar(50), Height double, Weight double >

Chiều cao được đo bằng centimet và Trọng lượng tính bằng kilogam.

VẤN ĐỀ:

Vấn đề của tôi là về việc lưu trữ đơn vị đo cho chiều cao và cân nặng.

HIỆU QUẢ CỦA TÔI ĐỂ GIẢI QUYẾT NÀY:

  • Tôi có thể thử thực hiện mô hình EAV.
  • Tôi có thể sửa đổi bảng bằng cách thêm các cột giữ đơn vị đo cho Chiều cao và Trọng lượng không? Một cái gì đó như dưới đây:

    PersonTable < # ID int, 
                    Name varchar(50), 
                    Height double, $ HeightUnit_Id int, 
                    Weight double, $ WeightUnit_Id int >
    
    Units < #ID int, Desription varchar(20) >
    

  • HeightUnit_Id và WeightUnit_Id là các khóa ngoại tham chiếu Id từ Đơn vị bảng.

    CÂU HỎI:

    Có giải pháp nào tốt hơn những giải pháp rõ ràng mà tôi đã đề cập ở trên không, vì tôi không thích cả hai (EAV có thể trở nên lộn xộn nếu làm không tốt và thêm "cột đơn vị" có vẻ như lãng phí không gian đối với tôi)?


    Là tất cả các đơn vị so sánh với nhau? Tức là tất cả các thuộc tính có thể được đo bằng mét nói? Nếu đó là trường hợp một ý tưởng là lưu trữ mọi thứ trong cùng một đơn vị (ví dụ như mét).
    Lennart

    @Lennart: Tôi không biết tôi có hiểu đúng về bạn không, nhưng tôi nghĩ câu trả lời cho câu hỏi của bạn là . Mỗi chiều cao được đo bằng mét.
    Luôn luôn học tập MớiStuff

    3
    Tôi sẽ thay đổi tên trường để làm rõ đơn vị đo lường nào được sử dụng cho. Chiều cao_cm, Cân nặng_kg. Sau đó sử dụng lớp ứng dụng để chấp nhận hoặc chuyển đổi các phép đo của người dùng. Bạn có quan tâm đến việc theo dõi các giá trị này theo thời gian?
    Jonathan Fite

    @JonathanFite: Bạn có lo lắng về việc theo dõi các giá trị này theo thời gian không? Tôi không hiểu câu hỏi. Hãy để tôi thử làm rõ: hiện tại, tôi không thấy ứng dụng kết nối với cơ sở dữ liệu sẽ tìm ra đơn vị nào được sử dụng. Chưa có kinh nghiệm và lần đầu tiên giải quyết vấn đề này, tôi thấy 2 giải pháp: nhà phát triển sẽ đọc một số loại tài liệu chính thức nơi các đơn vị được sử dụng sẽ được nêu hoặc tôi sẽ lưu trữ thông tin đó trong cơ sở dữ liệu. Tôi đã chọn giải pháp khác vì nó có vẻ hợp lý với tôi. Có lẽ tôi đang phản ứng thái quá ...
    Luôn luôn học tập MớiStuff 30/03/2016

    2
    Chà, cân nặng và chiều cao của mọi người thay đổi theo thời gian. Nếu đây là một cơ sở dữ liệu y tế đặc biệt thì thông tin lịch sử về những gì người này cân nhắc vào những ngày cụ thể có thể hữu ích. Đối với phần còn lại của câu hỏi của bạn, sẽ luôn có một tài liệu giải thích API và nếu bạn nêu trong tài liệu đó rằng "Chiều cao" là chiều cao của người được biểu thị bằng cm (hoặc mét hoặc tay) thì đó là lớp ứng dụng để hiển thị điều đó và chuyển đổi sang các đơn vị cục bộ / khác nếu cần thiết. Đừng chống lại lộ trình tài liệu quá mạnh mẽ, nó phổ biến trong ngành.
    Jonathan Fite

    Câu trả lời:


    6

    Giả sử rằng các loại đo lường sẽ không được trộn lẫn (tức là bất kỳ hàng cụ thể nào sẽ không trộn "kg" và "inch" HOẶC "pound" và "cm"), và cũng giả sử rằng ít nhất một phần ý định của Câu hỏi này liên quan đến điều này ngay bây giờ Câu hỏi liên quan đã xóa ( xin lưu ý rằng liên kết sau sẽ không hoạt động trừ khi bạn có đủ điểm rep để xem các mục bị xóa: Xử lý các thuộc tính tổng hợp với phần không đổi ), sau đó bạn chỉ cần chỉ ra hệ thống đo lường được sử dụng bởi hàng đó. Trong mô hình này, bạn sẽ có một MeasurementSystembảng duy nhất là Khóa ngoài cho bất kỳ bảng nào chứa các phép đo. Ví dụ: (sử dụng cú pháp Microsoft SQL Server):

    CREATE TABLE dbo.MeasurementSystem
    (
      MeasurementSystemID TINYINT NOT NULL
                          CONSTRAINT [PK_MeasurementSystem] PRIMARY KEY
                                     CLUSTERED,
      MeasurementSystemName NVARCHAR(50) NOT NULL
    );
    
    dbo.Person
    (
      PersonID            INT NOT NULL IDENTITY(1, 1)
                          CONSTRAINT [PK_Person] PRIMARY KEY
                                     CLUSTERED,
      MeasurementSystemID TINYINT NOT NULL
                          CONSTRAINT [FK_Person_MeasurementSystem]
                          FOREIGN KEY
                          REFERENCES dbo.MeasurementSystem (MeasurementSystemID),
      Name                NVARCHAR(50) NOT NULL
      Height              FLOAT,
      Weight              FLOAT,
      ...
    );
    
    INSERT INTO dbo.MeasurementSystem (MeasurementSystemID, MeasurementSystemName)
    VALUES (1, N'Metric');
    
    INSERT INTO dbo.MeasurementSystem (MeasurementSystemID, MeasurementSystemName)
    VALUES (2, N'United States customary units');
    

    Nếu bạn sẽ trộn các hệ thống đo lường và / hoặc nếu bạn sẽ cho phép nhiều đơn vị đo ngay cả khi bị giới hạn trong một hệ thống (nghĩa là cho phép "mm", "cm", "m"), thì sẽ cần phải có một lớp bổ sung để xử lý sự gia tăng độ chi tiết, bao gồm cần phải có một trường FK cho mỗi cột đo trong Personbảng. (Tôi có thể điều chỉnh mô hình ở trên để phù hợp với điều này nhưng sẽ chờ một số giải thích rõ ràng trước khi thực hiện).


    Hoặc, nếu sẽ có một số lượng kết hợp khá hữu hạn / giới hạn của các đơn vị trọng lượng và đơn vị chiều cao khác nhau, thì bạn có thể sử dụng mỗi hàng để thể hiện một trong các kết hợp được chấp nhận (ví dụ: "cm & kg", "m & kg", "mm & kg" / "inch & lb", "chân & lb"). Và sau đó "US" so với "Số liệu" chỉ là một thuộc tính của mỗi hàng của bảng tra cứu. Ví dụ:

    CREATE TABLE dbo.MeasurementUnit
    (
      MeasurementUnitID     TINYINT NOT NULL
                                    CONSTRAINT [PK_MeasurementUnit] PRIMARY KEY
                                               CLUSTERED,
      MeasurementSystem     CHAR(1) NOT NULL, -- "M" = Metric, "U" = US 
      MeasurementSystemName NVARCHAR(50) NOT NULL, -- "Metric" or "US Nonsense"
      HeightUnitsName       NVARCHAR(20) NOT NULL, -- "Centimeters"
      HeightUnitsAlias      NVARCHAR(5) NOT NULL, -- "cm"
      WeightUnitsName       NVARCHAR(20) NOT NULL, -- "Kilograms"
      WeightUnitsAlias      NVARCHAR(5) NOT NULL -- "kg"
    );
    
    dbo.Person
    (
      PersonID            INT NOT NULL IDENTITY(1, 1)
                          CONSTRAINT [PK_Person] PRIMARY KEY
                                     CLUSTERED,
      MeasurementUnitID   TINYINT NOT NULL
                                  CONSTRAINT [FK_Person_MeasurementUnit]
                                             FOREIGN KEY
                                            REFERENCES dbo.MeasurementUnit (MeasurementUnitID),
      Name                NVARCHAR(50) NOT NULL
      Height              FLOAT,
      Weight              FLOAT,
      ...
    );
    

    Hoặc, nếu cần phải có sự kết hợp của các Đơn vị vượt qua các hệ thống đo lường khác nhau, thì tôi sẽ sử dụng các bảng riêng biệt - một bảng cho mỗi loại đo lường: "WeightUnits" và "heightUnits". Tôi sẽ không trộn các đơn vị cho chiều cao và trọng lượng trong cùng một bảng (nghĩa là "kg" và "cm" trên các hàng khác nhau). Ví dụ:

    CREATE TABLE dbo.WeightUnit
    (
      WeightUnitID      TINYINT NOT NULL
                                CONSTRAINT [PK_WeightUnit] PRIMARY KEY
                                           CLUSTERED,
      MeasurementSystem CHAR(1) NOT NULL, -- "M" = Metric, "U" = US 
      WeightUnitName    NVARCHAR(50) NOT NULL, -- "Kilograms"
      WeightUnitAlias   NVARCHAR(5) NOT NULL -- "kg"
    );
    
    CREATE TABLE dbo.HeightUnit
    (
      HeightUnitID      TINYINT NOT NULL
                                CONSTRAINT [PK_HeightUnit] PRIMARY KEY
                                           CLUSTERED,
      MeasurementSystem CHAR(1) NOT NULL, -- "M" = Metric, "U" = US 
      HeightUnitName    NVARCHAR(50) NOT NULL, -- "Centimeters"
      HeightUnitAlias   NVARCHAR(5) NOT NULL -- "cm"
    );
    

    Trong mô hình này, mỗi loại đo lường trong bất kỳ bảng đã cho nào đều có FK riêng cho bảng tra cứu đơn vị đo của nó.


    Quả thực những gì bạn có ngay bây giờ chỉ là những gì tôi cần, chỉ có một cạm bẫy tiềm năng tôi phải cố gắng tránh. Các bảng được cung cấp chỉ là những ví dụ đơn giản minh họa vấn đề. Trong mô hình thực, tôi không biết liệu đơn vị khách hàng sử dụng có phải là tiêu chuẩn chính thức hay không. Đây là ví dụ ngu ngốc, nhưng chúng ta hãy nói rằng họ có thể sử dụng một số đơn vị khác cho Chiều cao khác với m / cm / mm (hoặc inch / foot / ...). Tôi tự hỏi nếu tôi có thể thay đổi dbo.MeasurementSystemvới các cột MeasuredParameterUnitUsedchỉ để được an toàn. Dữ liệu mẫu có thể giống như vậy 1 Height cm, 2 Weight kgv.v ... Cảm ơn bạn đã trả lời +1
    Luôn luôn học tập Mới

    1
    @AlwaysLearningNewStuff Có bao nhiêu kết hợp? Khách hàng có được phép nhập các loại số đo dạng tự do không? Xin đừng đơn giản hóa quá mức các ví dụ vì nó có thể đánh lừa và lãng phí rất nhiều thời gian cho cả hai chúng tôi. Nhưng nếu các kết hợp bị giới hạn, bạn có thể có một mục nhập cho mỗi kết hợp: "cm & kg", "m & kg", "mm & kg" / "inch & lb", "foot & lb". Và sau đó US vs Metric chỉ là một thuộc tính của mỗi hàng của bảng tra cứu đó. Nhưng tôi sẽ không trộn các đơn vị cho chiều cao và trọng lượng trong cùng một bảng (nghĩa là "kg" và "cm" trên các hàng khác nhau). Thay vào đó, tôi sẽ làm các bảng riêng biệt: HeightUnits/ WeightUnits.
    Solomon Rutzky

    1
    Tôi đã kiểm tra mọi thứ với khách hàng và họ thích ý tưởng bạn đề xuất. Tôi sẽ chính thức chấp nhận câu trả lời của bạn và trao tiền thưởng. Cảm ơn một lần nữa.
    Luôn luôn học tập MớiStuff 30/03/2016

    @AlwaysLearningNewStuff Cảm ơn và bạn hoan nghênh :-). Nhưng, ý tưởng nào chính xác? Tôi đã đề xuất một trong câu trả lời và sau đó 2 biến thể trong nhận xét ở trên. Nếu đó là một cái gì đó được đề cập trong bình luận thì tôi muốn cập nhật câu trả lời với thông tin đó. Vì vậy xin vui lòng cho tôi biết.
    Solomon Rutzky

    1
    Đó là câu đầu tiên, từ câu trả lời của bạn. Họ sử dụng các đơn vị tiêu chuẩn, vì vậy sẽ không có vấn đề. Tôi sẽ để lại bình luận của bạn vì tôi tin rằng nó có thể hữu ích cho các độc giả tương lai. Về mặt lưu ý, tôi nghĩ rằng tôi đã quá nhiệt tình với điều này, có lẽ các đơn vị nên được nêu ở đâu đó trong tài liệu. Sau khi nghiên cứu một chút, tôi đã đi đến kết luận rằng phương pháp này có thể là tiêu chuẩn của ngành ...
    Luôn luôn học tập Mới

    2

    Xem như câu hỏi này liên quan đến thiết kế như thế nào, các câu trả lời có thể sẽ được đánh giá khá cao ...

    Dưới đây là ý kiến ​​của tôi về cách nó nên được thiết kế. ;)

    Bảng để lưu trữ các đơn vị đo lường

    CREATE TABLE measure_unit (
      measure_unit_id, -- primary key
      name -- unique key .. values such as "inch" etc
    )
    

    Bàn người của bạn ...

    CREATE TABLE person (
      person_id, -- primary key
      name,
      measurement, -- example values would be 180
      measure_unit_id -- example values would be the pkey for centimeters
    )
    

    Và sau đó một bảng chuyển đổi

    CREATE TABLE measure_conversion (
      from_measure_unit_id, -- example would be pkey for centimeters
      to_measure_unit_id, -- example would be pkey for inches
      ratio -- example would be 0.393701 (centimeters * 0.393701 = inches)
      -- pkey is composite between both from and to values
    )
    

    Nếu một đơn vị đo không có mục trong bảng chuyển đổi đo cho một loại đơn vị cụ thể khác, thì sẽ không có chuyển đổi trực tiếp khả dụng. (Ví dụ: cm -> inch sẽ hoạt động, nhưng cm -> giờ sẽ không ..) Hiển thị số đo của bạn theo các đơn vị khác nhau sẽ dễ dàng.

    Đơn vị đo của bạn có thể là bất cứ thứ gì bạn muốn (khoảng cách / thời gian / v.v.) ... nhưng bạn có thể muốn thêm loại đo .. không chắc chắn nếu tôi lo lắng về điều đó - tùy thuộc vào trường hợp sử dụng.


    Sẽ không có chuyển đổi, mọi chiều cao sẽ được đo bằng mét và tôi có thể đảm bảo rằng trong tương lai sẽ không cần bất kỳ chuyển đổi nào. Tôi đoán điều này chỉ để lại cho tôi với measure_unitbảng, đúng không?
    AlwaysLearningNewStuff

    Nếu bạn chỉ sử dụng một đơn vị đo, thì thiết kế bạn đề xuất trong OP sẽ LÀM VIỆC ... nhưng tôi vẫn sẽ đề xuất thiết kế này (và vâng, bạn sẽ không còn có bảng đo_conversion)
    Joishi Bodio

    2

    Nếu đơn vị đo chiều cao / cân nặng của bạn thực sự cố định , tức là chiều cao = CM, Trọng lượng = KG, tôi sẽ không giới thiệu bất kỳ cột bổ sung (hoặc logic) nào để chỉ định đơn vị đo. Thay vào đó, những gì tôi sẽ làm chỉ là thay đổi tên cột như

    create table Person (ID int, Name varchar(50), Height_CM double, Weight_KG double)

    Bằng cách này, tôi có thể xóa bất kỳ nhầm lẫn nào về đơn vị đo cho các cột Chiều cao và Trọng lượng.


    0

    Nó phụ thuộc vào những gì bạn đang thiết kế ... một hệ thống OLTP được chuẩn hóa sẽ có một bảng Biện pháp riêng (hoặc một số tên như vậy) để cung cấp tính toàn vẹn tham chiếu và tối ưu hóa hiệu suất cho từng đơn vị đo lường có thể.

    Nếu bạn đang phân tích và bạn thường xuyên xử lý các đơn vị và thực hiện ít chuyển đổi hơn, thì nó có thể được lưu trữ dưới dạng một thuộc tính. Điều này vẫn sẽ là hiếm - một cái gì đó như phản hồi khảo sát hoặc một tiêu chuẩn ngành như cảnh quay vuông cho bất động sản. Nhưng những gì khác được đo lường và có ý nghĩa trong bất động sản? kế hoạch sàn? Bây giờ chúng ta có inch ... và hình vuông và hình khối. Chúng tôi đang trở lại một thiết kế bình thường.

    Đối với chiều cao, một loạt các biện pháp được áp dụng và có ý nghĩa hoàn hảo trong các bối cảnh khác nhau. Có lẽ là một ý tưởng tốt để sử dụng một thiết kế như thế này:

    dbo.PersonHeight
    Height     MeasureFK
    62           2
    
    dbo.UnitsOfMeasure
    MeasureID  MeasureDescription
    2          Inches
    3          Centimeters

    Với thiết kế như vậy, bạn có thể dễ dàng tạo bảng tra cứu / chuyển đổi ngay bây giờ:

    dbo.UnitConversions
    FromMeasureID    ToMeasureID    Conversion
    2                 3             0.39370079

    Sẽ không có chuyển đổi, mọi chiều cao sẽ được đo bằng mét và tôi có thể đảm bảo rằng trong tương lai sẽ không cần bất kỳ chuyển đổi nào.
    AlwaysLearningNewStuff
    Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
    Licensed under cc by-sa 3.0 with attribution required.