2011-11-26 42 views
6

Tôi cần giải pháp sạch và hiệu quả nhất cho trường hợp của mình. Tôi đang cố gắng để lưu trữ Marks của học sinh trong một DB MySQL. Một sinh viên có thể là "ABSENT" hoặc "COPY CASE", tôi muốn lưu trữ thông tin đó cũng trong DB.Lưu trữ Enums trong Cơ sở dữ liệu MySQL

Tôi đã nghĩ đến việc chỉ định mã cho trường hợp trên như -1 cho ABSENT, -2 cho COPY CASE, v.v. Mã này sẽ chỉ được lưu trữ trong cột Đánh dấu.

Hơn bao giờ hết, khi đọc chúng với truy vấn chọn, tôi sẽ nhận được giá trị hiển thị của chúng, tức là chỉ ABSENT, COPY CASE, v.v.

Tất cả những điều này có thể đạt được ở cuối DB không?

Hoặc tôi có cần thực hiện những việc này ở cấp Ứng dụng không?

Có bất kỳ API nào có sẵn cho Java cho chức năng như vậy không?

Trả lời

4

thế nào về việc lưu trữ của nó name() (String phiên bản) để DB và tạo ra nó trở lại trong khi đọc từ DB sử dụng valueOf()

1

Nếu cơ quan đại diện chuỗi enum là chuỗi khá nặng, và cơ sở dữ liệu lớn (kiểm tra chống lại những sự đếm được thường xuyên), tôi có thể ánh xạ từng enum đến một hằng số nguyên (không, không phải là ordinal(), nhưng giá trị số nguyên tùy chỉnh của riêng bạn) và có các phương thức trên enum để nhận và tạo một enum từ các giá trị này. Bằng cách này, bạn sẽ có thể lưu trữ các enums khá hiệu quả.

public enum Status { 

    ABSENT(1), COPY_PASTE(2); 

    int value; 

    private Status(int value) { 
     this.value = value; 
    } 

    public int getValue() { 
     return this.value; 
    } 

    public static Status ofStatusCode(int value) { 
     // retrieve status from status code 
    } 

} 
+0

Chỉ cần một lưu ý rằng, mặc dù tôi không đồng ý với Sanjay rằng việc sử dụng [kiểu dữ liệu] (http://dev.mysql.com/doc/ refman/5.0/en/integer-types.html) đại diện cho enum nói chung là hiệu quả hơn việc sử dụng [string types] (http://dev.mysql.com/doc/refman/5.0/en/char.html) (hiệu suất và không gian khôn ngoan), Enum loại là một ngoại lệ, nó sẽ sử dụng một 16 bit unsigned (ngắn) nội bộ để lưu trữ các giá trị hiệu quả, và tôi không bao giờ có vấn đề hiệu suất với nó cả. –

0

MySQL có riêng ENUM type. Và như @Jigar Chỉ ra, bạn có thể sử dụng Enum.getName để lấy Java's String đại diện cho enum cho persistence, lấy trường từ cơ sở dữ liệu dưới dạng String và sử dụng Enum.valueOf để tải lại hằng số enum.

Bạn cũng có thể sử dụng Enum.ordinal() + 1 để có được một số nguyên cho persistence (MySQL cũng hỗ trợ sử dụng các chỉ số số nguyên trực tiếp với loại ENUM) và ban hành một truy vấn như:

SELECT enum_col-1 FROM tbl_name; 

để lấy thứ trở lại (nó sẽ lấy - 1 cho các hàng có giá trị enum không hợp lệ).

Thêm MyEnumType value = MyEnumType.values()[ordinal] để chuyển đổi trở lại thành loại enum Java. Dù sao, tôi nghĩ rằng giải pháp dựa trên String là sạch hơn và thanh lịch hơn, cộng với an toàn hơn về lâu dài (nếu bạn cần thay đổi thứ tự của java Enum, hoặc thêm các giá trị enum mới ở giữa hiện tại những người, bạn sẽ cảm ơn chính mình cho đi với chiến lược dựa trên String để bắt đầu với).

6

mysql hỗ trợ enums:

CREATE TABLE students (name varchar(64), mark ENUM('ABSENT','COPY CASE')); 
INSERT INTO students VALUES ('john', 'COPY CASE'); 

Trong java, bạn có thể điều trị cột này như một cột kiểu chuỗi, nhưng trong cơ sở dữ liệu, các giá trị được lưu trữ một cách hiệu quả, và cố gắng để lưu trữ một giá trị không chứa trong enum sẽ dẫn đến lỗi.

+1

Yêu cầu thứ hai có thể được đáp ứng bằng tính toàn vẹn tham chiếu. –

1

Tôi đã nghĩ đến việc lưu trữ mã cho trường hợp trên như -1 cho ABSENT, -2 cho COPY CASE, v.v. Mã này sẽ chỉ được lưu trữ trong cột Đánh dấu.

Tôi thà thích có một cột riêng biệt, nói status nắm giữ các giá trị như ABSENT, COPY CASE và một giá trị mặc định như APPEARED

Và cột dấu sẽ ở lại riêng biệt.

Trong lớp xem, bạn có thể làm một cái gì đó giống như

 
if(status is 'APPEARED') 
show marks field 
else 
show status field 
+1

Điều này chắc chắn tốt hơn là lưu trữ cả nhãn hiệu và trạng thái kiểm tra trong cùng một cột. Và bạn sẽ không có (thậm chí vô tình) bất kỳ kết quả sai nào trong các truy vấn tìm kiếm ví dụ 'AVG (đánh dấu)' –

Các vấn đề liên quan