Lưu trữ giới tính (giới tính) trong cơ sở dữ liệu


130

Tôi muốn lưu trữ giới tính của người dùng trong cơ sở dữ liệu với chi phí (kích thước / hiệu suất) càng ít càng tốt.

Cho đến nay, 3 kịch bản đến với tâm trí

  1. Int - căn chỉnh với Enum trong mã (1 = Nam, 2 = Nữ, 3 = ...)
  2. char (1) - Lưu trữ m , f hoặc một mã định danh ký tự đơn khác
  3. Bit (boolean) - có tên trường thích hợp cho tùy chọn này không?

Lý do tôi hỏi là vì điều này câu trả lời mà nói rằng charsnhỏ hơn so với các phép toán luận .

Tôi nên làm rõ rằng tôi đang sử dụng MS SQL 2008, trong thực tế DOES có kiểu dữ liệu bit.


1
FWIW, câu hỏi SO mà bạn tham chiếu đề cập đến cách .NET thể hiện các loại này trong bộ nhớ. Nó không liên quan gì đến cách SQL Server thể hiện chúng. bit <= char. msdn.microsoft.com/en-us/l Library / ms177603.aspx
Matt

1
Bạn đang sử dụng lĩnh vực giới tính để làm gì? Nó có thể chỉ là một chuỗi, vì vậy mọi người có thể nhập những gì họ thích? Cố gắng liệt kê tất cả các câu trả lời có thể cho câu hỏi này sẽ rất khó khăn.
chiếu vào

@ThePasbah: Tôi nghĩ rằng tùy chọn thông thường về cơ bản là m / f / khác, vì vậy, vernary như bạn đề nghị là tốt. Bạn có thể muốn phân biệt "khác" với "không xác định" (như trong "Tôi không nói" và / hoặc "chúng tôi chưa hỏi người dùng"). Tôi không biết những người có giới tính muốn có giá trị dấu phẩy động với thanh trượt họ có thể đặt mỗi ngày; Tôi đoán là hầu hết trong số họ (và những người không có giới tính truyền thống khác) sẽ rất vui khi chọn "người khác" hoặc "không xác định" trên hầu hết mọi trang web. Nhưng không, tôi không nghĩ yêu cầu "sex" thay vì "giới tính" sẽ là một ý tưởng hay.
Peter Cordes

1
@PeterCordes Tôi không biết rõ về "chất lỏng giới", ở làng tôi, bạn là đàn ông, phụ nữ ... hay bò. Nếu thể loại này bây giờ trôi chảy, việc tạo ra một thang giá trị như đối với âm thanh của máy tính có vẻ hơi quá để hỏi. Ở nước tôi, chúng tôi muốn hỏi về giới tính, nó ít phức tạp hơn. Ồ, đừng tin rằng chúng ta đang ở thời kỳ đồ đá cho đến nay, eh! Chúng tôi đã phát hiện ra Thiên Chúa và chúng tôi là những người độc thần trong phần lớn kể từ lần thực dân cuối cùng.
Cuộc cách mạng cho Monica

2
@PeterCordes: khi yêu cầu những thứ như vậy trong môi trường chính trị hiện tại sẽ mang lại lợi thế cho mọi người bằng cách cung cấp cho họ sự thống trị so với những người khác, ngay khi bạn bao gồm một thanh trượt giá trị nổi, ai đó sẽ đưa ra yêu cầu đa chiều. "Chỉ một đường trượt? Bạn đang ở thời kỳ đồ đá?"
vsz

Câu trả lời:


82

Tôi gọi cột là "giới tính".

Data Type   Bytes Taken          Number/Range of Values
------------------------------------------------
TinyINT     1                    255 (zero to 255)
INT         4            -       2,147,483,648 to 2,147,483,647
BIT         1 (2 if 9+ columns)  2 (0 and 1)
CHAR(1)     1                    26 if case insensitive, 52 otherwise

Các BIT kiểu dữ liệu có thể được loại trừ bởi vì nó chỉ hỗ trợ hai giới tính có thể đó là không đủ. Mặc dù INT hỗ trợ nhiều hơn hai tùy chọn, phải mất 4 byte - hiệu suất sẽ tốt hơn với kiểu dữ liệu nhỏ hơn / hẹp hơn.

CHAR(1)có lợi thế hơn TinyINT - cả hai đều có cùng số byte, nhưng CHAR cung cấp số lượng giá trị hẹp hơn. Việc sử dụng CHAR(1)sẽ làm cho việc sử dụng các khóa tự nhiên "m", "f", v.v ... so với việc sử dụng dữ liệu số được gọi là khóa thay thế / khóa nhân tạo. CHAR(1)cũng được hỗ trợ trên bất kỳ cơ sở dữ liệu nào, nếu cần phải chuyển.

Phần kết luận

Tôi sẽ sử dụng Tùy chọn 2: CHAR (1).

Phụ lục

Một chỉ mục trên cột giới có thể sẽ không giúp ích vì không có giá trị trong một chỉ mục trên cột có số lượng thẻ thấp. Có nghĩa là, không có đủ sự đa dạng trong các giá trị để chỉ mục cung cấp bất kỳ giá trị nào.


Bất kỳ tài liệu tham khảo để thực hiện? Tôi biết rằng nó gần như tối ưu hóa vi mô mà tôi không nên làm, nhưng đó là thức ăn cho tâm trí tò mò của tôi.
Marko

Cảm ơn @OMG Ponies, còn hiệu suất thì sao? Một char sẽ tốn kém hơn một chút trong trường hợp này?
Marko

4
@Marko: Như tôi đã nói trước đây, họ bằng nhau. Nhưng một chỉ mục có thể sẽ không giúp ích vì không có giá trị trong một chỉ mục trên cột có số lượng thẻ thấp. Có nghĩa là, không có đủ sự đa dạng trong các giá trị để chỉ mục cung cấp bất kỳ giá trị nào.
Ngựa Non OMG

1
Hiệu suất thực sự sẽ được sử dụng tốt hơn bao nhiêu , giả sử, kiểu dữ liệu 4 byte trên nền tảng 64 bit? Chỉ cần nói ... ;-)
Craig

1
Tôi sẽ gắn bó với bit, vì chỉ có hai giới tính. Tuy nhiên, câu hỏi ban đầu của OP vẫn là: tên cột sẽ là gì? "IsMale" hoặc "IsFirting" hơi lạ ...
Mateus Felipe

180

Đã có một tiêu chuẩn ISO cho việc này; không cần phải phát minh ra sơ đồ của riêng bạn:

http://en.wikipedia.org/wiki/ISO_5218

Theo tiêu chuẩn, cột phải được gọi là "Giới tính" và loại dữ liệu 'gần nhất' sẽ là cực nhỏ với ràng buộc KIỂM TRA hoặc bảng tra cứu nếu phù hợp.


4
Tại sao nó bỏ qua đến 9 cho 'không áp dụng'? Còn 3-8 thì sao?
Kenmore

4
Đây là cho tình dục. OP đặc biệt yêu cầu giới tính. Giới tính và giới có thể có các giá trị khác nhau có thể cần phải được nắm bắt.
indigochild

2
@indigochild OP sử dụng cả hai từ trong tiêu đề câu hỏi và rõ ràng coi chúng là tương đương, ít nhất là cho trường hợp sử dụng của mình (YMMV). Quan điểm của tôi đơn giản là một tiêu chuẩn ISO tồn tại trong lĩnh vực này và bạn không bao giờ nên lãng phí thời gian vào việc đưa ra kế hoạch của riêng mình khi một tiêu chuẩn chính thức tồn tại. Tất nhiên trừ khi tiêu chuẩn đó không bao gồm trường hợp cụ thể của bạn, điều này là hoàn toàn có thể.
Pondlife

1
Đây phải là câu trả lời được chấp nhận. Nó tập trung vào tính toàn vẹn dữ liệu (là ~ mãi mãi) thay vì tối ưu hóa (là tình huống).
Paul Cantrell

1
Điều này chắc chắn nên là câu trả lời. @PeterCordes ISO này được sử dụng cho Giới tính (giới tính sinh học) chứ không phải Giới tính (những gì bạn xác định là) - giải thích ở đây . Tôi đoán trong trường hợp muốn lưu trữ giới tính (mà tôi không biết bạn sử dụng cái này để làm gì), một int nhỏ vẫn đủ tốt miễn là bạn muốn lưu trữ ít hơn 255 giới tính (bằng cách nói từ 0 = không biết / không muốn tuyên bố, 1 = đàn ông, 2 = phụ nữ, 3 = đàn ông xác định là phụ nữ, v.v.)
SolidTerre

43

Trong y học có bốn giới tính: nam, nữ, không xác định và không rõ. Bạn có thể không cần cả bốn nhưng chắc chắn bạn cần 1, 2 và 4. Không phù hợp để có giá trị mặc định cho kiểu dữ liệu này. Thậm chí ít hơn để coi nó là Boolean với trạng thái 'là' và 'không'.


1
@EJP, thú vị. Bạn có một tài liệu tham khảo về điều này?
Marko

11
Cha tôi, MD BS FRACP.
Hầu tước Lorne

Dựa trên thông tin này, tôi sẽ đi cùng TinyIntvới một enum (như Hugo gợi ý) và đi với ít nhất 1, 2 và 3 (Khác).
Tôi chấp nhận

1
@EJP, mặc dù câu trả lời của bạn có thể đúng, nhưng KHÔNG nói tôi nên sử dụng kiểu dữ liệu nào, mà là - giới tính chính xác (về mặt kỹ thuật) là gì.
Marko

17
Từ điển dữ liệu của Dịch vụ Y tế Quốc gia Vương quốc Anh (NHS) xác định bốn giá trị: 0 = Not Known, 1 = Male, 2 = Female, 9 = Not Specified, làm tăng giá trị của các giá trị ISO 5218 . Lưu ý có hai loại : giới tính khi đăng ký (thường là ngay sau khi sinh) và hiện tại.
onedaywhen ngày

3

Một Int(hoặc TinyInt) liên kết với một Enumlĩnh vực sẽ là phương pháp của tôi.

Đầu tiên, nếu bạn có một bittrường duy nhất trong cơ sở dữ liệu, hàng vẫn sẽ sử dụng một byte đầy đủ, cho đến khi tiết kiệm không gian, nó chỉ trả hết nếu bạn có nhiều bittrường.

Thứ hai, chuỗi / ký tự có cảm giác "giá trị ma thuật" đối với chúng, bất kể chúng có vẻ rõ ràng như thế nào tại thời điểm thiết kế. Chưa kể, nó cho phép mọi người lưu trữ bất kỳ giá trị nào mà họ không nhất thiết phải ánh xạ tới bất kỳ thứ gì rõ ràng.

Thứ ba, một giá trị số dễ dàng hơn nhiều (và thực hành tốt hơn) để tạo bảng tra cứu, để thực thi tính toàn vẹn tham chiếu và có thể tương quan 1-1 với enum, do đó, có sự tương đương trong việc lưu trữ giá trị trong bộ nhớ ứng dụng hoặc trong cơ sở dữ liệu.


2

Tôi sử dụng char 'f', 'm' và 'u' vì tôi phỏng đoán giới tính từ tên, giọng nói và cuộc trò chuyện và đôi khi không biết giới tính. Quyết định cuối cùng là ý kiến ​​của họ.

Nó thực sự phụ thuộc vào mức độ bạn biết người đó và liệu tiêu chí của bạn là hình thức vật lý hay bản sắc cá nhân. Một nhà tâm lý học có thể cần các lựa chọn bổ sung - chuyển sang nữ, chuyển sang nam, chuyển sang nữ, chuyển sang nam, lưỡng tính và chưa quyết định. Với 9 tùy chọn, không được xác định rõ ràng bởi một ký tự, tôi có thể đi theo lời khuyên của Hugo về số nguyên nhỏ.


Không về chủ đề. Đó không phải là một câu trả lời.
hod

1

Tùy chọn 3 là đặt cược tốt nhất của bạn, nhưng không phải tất cả các công cụ DB đều có loại "bit". Nếu bạn không có một chút, thì TinyINT sẽ là lựa chọn tốt nhất của bạn.


-5
CREATE TABLE Admission (
    Rno INT PRIMARY KEY AUTO_INCREMENT,
    Name VARCHAR(25) NOT NULL,
    Gender ENUM('M','F'),
    Boolean_Valu boolean,
    Dob Date,
    Fees numeric(7,2) NOT NULL
);




insert into Admission (Name,Gender,Boolean_Valu,Dob,Fees)values('Raj','M',true,'1990-07-12',50000);
insert into Admission (Name,Gender,Boolean_Valu,Dob,Fees)values('Rani','F',false,'1994-05-10',15000);
select * from admission;

nhập mô tả liên kết ở đây


-5

Tôi sẽ đi với Tùy chọn 3 nhưng nhiều cột bit NON NULLABLE thay vì một cột. IsMale (1 = Có / 0 = Không) IsFirting (1 = Có / 0 = Không)

if requried: IsUn UnknownGender (1 = Có / 0 = Không), v.v.

Điều này giúp dễ đọc các định nghĩa, dễ mở rộng, dễ lập trình, không có khả năng sử dụng các giá trị bên ngoài miền và không yêu cầu bảng tra cứu thứ hai + các ràng buộc FK hoặc CHECK để khóa các giá trị.

EDIT: Sửa chữa, bạn cần ít nhất một ràng buộc để đảm bảo các cờ thiết lập là hợp lệ.


Thật tuyệt khi nghe lý do tại sao câu trả lời của tôi bị hạ thấp?
HansLindgren

Không có ràng buộc, không có gì ngăn tất cả các cột là 1 hoặc tất cả các cột là 0. Điều này là vô nghĩa, vì vậy lược đồ của bạn không đáp ứng một trong các yêu cầu của bạn.
Jay Kominek

Có, bạn đúng rằng bạn cần một ràng buộc để kiểm tra xem số lượng cờ chính xác đã được 'kiểm tra' chưa. Tuy nhiên, tôi không nghĩ rằng tất cả các phiếu bầu là vì thiếu sót đó ...
HansLindgren

Đó là một câu hỏi được truy cập rất nhiều (hãy xem các câu trả lời cho một số câu trả lời khác!), Và bạn đã đến nhiều năm sau đó và thêm một câu trả lời cho mã hóa một nóng, một kỹ thuật được dạy rộng rãi, thậm chí không có vài thuộc tính cụ thể mà bạn gán cho nó. Tôi không nghĩ rằng việc bầu bạn dưới 0 là đúng, nhưng tôi cũng không ngạc nhiên khi điều đó xảy ra.
Jay Kominek
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.