데이터베이스에 Enum을 저장하는 방법
데이터베이스에 enum을 저장하는 가장 좋은 방법은 무엇입니까?
가 제공하는 것은 있습니다.name()
★★★★★★★★★★★★★★★★★」valueOf()
메서드를 사용하여 열거값을 String으로 변환한 후 되돌립니다.그러나 이러한 값을 저장할 수 있는 다른(유연한) 옵션이 있습니까?
숫자로 한 방법이 요?ordinal()
전하지? ??
갱신하다
멋지고 빠른 답변 감사합니다!내가 의심했던 대로였다.
단, 툴킷에 대한 주의사항:그것도 한 가지 방법이에요.문제는 작성하는 각 열거형에 동일한 메서드를 추가해야 한다는 것입니다.이는 많은 중복된 코드이며 현재 Java는 이에 대한 솔루션을 지원하지 않습니다(Java Enum은 다른 클래스를 확장할 수 없습니다).
열거를 더 이상 숫자 서수 값으로 저장하지 않습니다. 디버깅 및 지원이 너무 어렵습니다.문자열로 변환된 실제 열거값을 저장합니다.
public enum Suit { Spade, Heart, Diamond, Club }
Suit theSuit = Suit.Heart;
szQuery = "INSERT INTO Customers (Name, Suit) " +
"VALUES ('Ian Boyd', %s)".format(theSuit.name());
그 후 다음과 같이 응답합니다.
Suit theSuit = Suit.valueOf(reader["Suit"]);
이 문제는 과거에 Enterprise Manager를 응시하여 다음 사항을 해독하려고 했던 것입니다.
Name Suit
------------ ----
Kylie Guénin 2
Ian Boyd 1
시구
Name Suit
------------ -------
Kylie Guénin Diamond
Ian Boyd Heart
후자가 훨씬 더 쉽다.전자는 소스 코드를 가져와 열거 멤버에 할당된 수치를 찾아야 했습니다.
네, 더 많은 공간이 필요하지만 열거형 멤버 이름은 짧고 하드 드라이브는 저렴하기 때문에 문제가 있을 때 도움을 주는 것이 훨씬 더 가치가 있습니다.
게다가 수치를 사용하는 경우는, 그 값에 관련지어집니다.이전 수치를 강제하지 않고는 부재를 삽입하거나 재배열할 수 없습니다.예를 들어, Suit 열거를 다음과 같이 변경합니다.
public enum Suit { Unknown, Heart, Club, Diamond, Spade }
다음과 같이 해야 합니다.
public enum Suit {
Unknown = 4,
Heart = 1,
Club = 3,
Diamond = 2,
Spade = 0 }
데이터베이스에 저장된 레거시 수치를 유지하기 위해 사용합니다.
데이터베이스에서 정렬하는 방법
질문이 떠오릅니다. 예를 들어, 내가 값을 정렬하고 싶다고 가정해 보겠습니다.어떤 사람들은 그것들을 분류하기를 원할 수 있다.enum
가 없습니다물론 열거치의 수치로 카드를 정렬하는 것은 의미가 없습니다.
SELECT Suit FROM Cards
ORDER BY SuitID; --where SuitID is integer value(4,1,3,2,0)
Suit
------
Spade
Heart
Diamond
Club
Unknown
이 순서는 우리가 원하는 순서가 아닙니다.이 순서는 열거형 순서로 되어 있습니다.
SELECT Suit FROM Cards
ORDER BY CASE SuitID OF
WHEN 4 THEN 0 --Unknown first
WHEN 1 THEN 1 --Heart
WHEN 3 THEN 2 --Club
WHEN 2 THEN 3 --Diamond
WHEN 0 THEN 4 --Spade
ELSE 999 END
문자열을 저장하는 경우 정수 값을 저장하는 경우와 동일한 작업이 필요합니다.
SELECT Suit FROM Cards
ORDER BY Suit; --where Suit is an enum name
Suit
-------
Club
Diamond
Heart
Spade
Unknown
그러나 우리가 원하는 순서는 아닙니다. 우리는 그것들을 열거 순서로 원합니다.
SELECT Suit FROM Cards
ORDER BY CASE Suit OF
WHEN 'Unknown' THEN 0
WHEN 'Heart' THEN 1
WHEN 'Club' THEN 2
WHEN 'Diamond' THEN 3
WHEN 'Space' THEN 4
ELSE 999 END
이러한 순위는 사용자 인터페이스에 속한다고 생각합니다.열거값을 기준으로 항목을 정렬하는 경우 잘못된 작업을 수행하고 있습니다.
하지만 당신이 정말 그렇게 하고 싶다면, 내가 만들거야Suits
치수 테이블:
슈트 | 슈트 아이디 | 순위 | 색. |
---|---|---|---|
알 수 없는 | 4 | 0 | 특수한 순서 |
하트 | 1 | 1 | 빨간. |
클럽 | 3 | 2 | 블랙입니다. |
다이아몬드 | 2 | 3 | 빨간. |
스페이드 | 0 | 4 | 블랙입니다. |
이렇게 하면 Kissing Kings New Deck Order를 사용하도록 카드를 변경할 때 모든 데이터를 폐기하지 않고 표시 목적으로 변경할 수 있습니다.
슈트 | 슈트 아이디 | 순위 | 색. | 카드 주문 |
---|---|---|---|---|
알 수 없는 | 4 | 0 | 특수한 순서 | 특수한 순서 |
스페이드 | 0 | 1 | 블랙입니다. | 1 |
다이아몬드 | 2 | 2 | 빨간. | 1 |
클럽 | 3 | 3 | 블랙입니다. | -1 |
하트 | 1 | 4 | 빨간. | -1 |
이제 내부 프로그래밍 세부사항(열람 이름, 열거 값)을 사용자를 위한 디스플레이 설정으로 분리합니다.
SELECT Cards.Suit
FROM Cards
INNER JOIN Suits ON Cards.Suit = Suits.Suit
ORDER BY Suits.Rank,
Card.Rank*Suits.CardOrder
피해야 할 특별한 성능 이유가 없는 한 열거를 위해 별도의 표를 사용할 것을 권장합니다.추가 검색으로 인해 실제로 문제가 발생하지 않는 한 외부 키 무결성을 사용하십시오.
정장 테이블:
suit_id suit_name
1 Clubs
2 Hearts
3 Spades
4 Diamonds
플레이어 테이블
player_name suit_id
Ian Boyd 4
Shelby Lake 2
- 열거를 동작(우선순위 등)이 있는 클래스로 재팩터링하는 경우 데이터베이스는 이미 올바르게 모델링합니다.
- 스키마가 정규화되었기 때문에 DBA는 만족합니다(오타가 있을 수도 있고 없을 수도 있는 문자열 전체가 아닌 플레이어당 하나의 정수를 저장합니다).
- 값 「」 「」( 「」)
suit_id
는 열거값과는 무관하며 다른 언어의 데이터에도 도움이 됩니다.
말씀하신 대로 서수는 조금 위험합니다.예를 들어 다음과 같습니다.
public enum Boolean {
TRUE, FALSE
}
public class BooleanTest {
@Test
public void testEnum() {
assertEquals(0, Boolean.TRUE.ordinal());
assertEquals(1, Boolean.FALSE.ordinal());
}
}
이를 서수로 저장한 경우 다음과 같은 행이 있을 수 있습니다.
> SELECT STATEMENT, TRUTH FROM CALL_MY_BLUFF
"Alice is a boy" 1
"Graham is a boy" 0
Boolean을 업데이트하면 어떻게 됩니까?
public enum Boolean {
TRUE, FILE_NOT_FOUND, FALSE
}
즉, 모든 거짓말이 'file-not-found'로 잘못 해석됩니다.
문자열 표현만 사용하는 것이 좋습니다.
은 String을 입니다.name()
value. DB에 쓸 때는 sproc를 사용하여 값을 삽입하고 읽을 때는 View를 사용할 수 있습니다.이와 같이 Enum이 변경되면 sproc/view에 데이터를 열거값으로 표시할 수 있는 간접 레벨이 DB에 "임포즈"되지 않고 표시됩니다.
Ordinal 값이 아닌 Enum String 값을 데이터베이스에 유지하는 것이 목표인 동일한 문제에 직면해 있습니다.
는 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★@Enumerated(EnumType.STRING)
을 사용하다
를 들어, '하다'가 .Enum
★★★★★★★
public enum FurthitMethod {
Apple,
Orange,
Lemon
}
에서 " " 를 합니다.@Enumerated(EnumType.STRING)
:
@Enumerated(EnumType.STRING)
@Column(name = "Fruits")
public FurthitMethod getFuritMethod() {
return fruitMethod;
}
public void setFruitMethod(FurthitMethod authenticationMethod) {
this.fruitMethod= fruitMethod;
}
Database로 은 ""로 APPLE
", "ORANGE
" " " " "LEMON
열거형 이름 자체를 저장합니다.그게 더 읽기 쉬워요.
열거형에는 제한된 값 집합이 있는 열거형에 추가 속성을 추가하는 작업을 수행했습니다.를 들어에서는 '아까', '아까', '아까', '아까', '아까', '아까',char
속성(a)char
(미국의)
public enum EmailStatus {
EMAIL_NEW('N'), EMAIL_SENT('S'), EMAIL_FAILED('F'), EMAIL_SKIPPED('K'), UNDEFINED('-');
private char dbChar = '-';
EmailStatus(char statusChar) {
this.dbChar = statusChar;
}
public char statusChar() {
return dbChar;
}
public static EmailStatus getFromStatusChar(char statusChar) {
switch (statusChar) {
case 'N':
return EMAIL_NEW;
case 'S':
return EMAIL_SENT;
case 'F':
return EMAIL_FAILED;
case 'K':
return EMAIL_SKIPPED;
default:
return UNDEFINED;
}
}
}
값이 는 '아까운가 '아까운가', '아까운가보다' 이런 요.Map
enum을 합니다.getFromXYZ
smiled smethod small method
큰 데이터베이스라면 수치표현의 크기와 속도상의 이점을 잃을 수 없습니다.Enum을 나타내는 데이터베이스 테이블로 끝나는 경우가 많습니다.
외부 키를 선언하여 데이터베이스 일관성을 적용할 수 있습니다. 그러나 경우에 따라서는 모든 트랜잭션에 비용을 부과하는 외부 키 제약 조건으로 선언하지 않는 것이 좋습니다.선택한 시간에 다음 항목을 정기적으로 검사하여 일관성을 보장할 수 있습니다.
SELECT reftable.* FROM reftable
LEFT JOIN enumtable ON reftable.enum_ref_id = enumtable.enum_id
WHERE enumtable.enum_id IS NULL;
이 솔루션의 나머지 절반은 Java 열거 테이블과 데이터베이스 열거 테이블의 내용이 동일한지 확인하는 테스트 코드를 작성하는 것입니다.그것은 독자를 위한 연습으로 남겨져 있다.
데이터베이스에 enum을 문자열로 저장하는 경우 유틸리티 메서드를 생성하여 다음 열거형을 직렬화할 수 있습니다.
public static String getSerializedForm(Enum<?> enumVal) {
String name = enumVal.name();
// possibly quote value?
return name;
}
public static <E extends Enum<E>> E deserialize(Class<E> enumType, String dbVal) {
// possibly handle unknown values, below throws IllegalArgEx
return Enum.valueOf(enumType, dbVal.trim());
}
// Sample use:
String dbVal = getSerializedForm(Suit.SPADE);
// save dbVal to db in larger insert/update ...
Suit suit = deserialize(Suit.class, dbVal);
제 경험상 에넘을 어디에나 유지하는 가장 안전한 방법은 추가 코드 값 또는 id(JeeBee의 답변의 일종의 진화)를 사용하는 것입니다.이것은 아이디어의 좋은 예가 될 수 있습니다.
enum Race {
HUMAN ("human"),
ELF ("elf"),
DWARF ("dwarf");
private final String code;
private Race(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}
이제 코드별로 열거 상수를 참조하는 지속성을 사용할 수 있습니다.이름을 할 수 있습니다( " " " " " " " " " " " " 등).DWARF("dwarf")
로로 합니다.GNOME("dwarf")
를 참조해 주세요.
좋아, 이 개념으로 좀 더 깊이 들어가봐.다음은 열거값을 찾는 데 도움이 되는 몇 가지 유틸리티 메서드입니다. 먼저 접근 방식을 확장합니다.
interface CodeValue {
String getCode();
}
그리고 우리의 열거형으로 그것을 구현해 보자.
enum Race implement CodeValue {...}
다음은 마법 검색 방법입니다.
static <T extends Enum & CodeValue> T resolveByCode(Class<T> enumClass, String code) {
T[] enumConstants = enumClass.getEnumConstants();
for (T entry : enumConstants) {
if (entry.getCode().equals(code)) return entry;
}
// In case we failed to find it, return null.
// I'd recommend you make some log record here to get notified about wrong logic, perhaps.
return null;
}
그것을하세요.Race race = resolveByCode(Race.class, "elf")
enum 필드 하나에 대해 OR 관계가 있는 여러 값이 있습니다.의 개념.바이트나 int 등의 열거형을 데이터베이스에 저장하고 코드에서 FlagsAttribute를 사용하는 NET.
http://blogs.msdn.com/b/efdesign/archive/2011/06/29/enumeration-support-in-entity-framework.aspx
enum 상수에는 이름 변경과 enum의 resorting 모두에서 생존할 수 있는 추가 값을 사용할 수 있습니다.
public enum MyEnum {
MyFirstValue(10),
MyFirstAndAHalfValue(15),
MySecondValue(20);
public int getId() {
return id;
}
public static MyEnum of(int id) {
for (MyEnum e : values()) {
if (id == e.id) {
return e;
}
}
return null;
}
MyEnum(int id) {
this.id = id;
}
private final int id;
}
열거형에서 ID를 가져오려면:
int id = MyFirstValue.getId();
ID에서 열거를 가져오려면:
MyEnum e = MyEnum.of(id);
열거형 이름을 변경해야 할 경우 혼동을 피하기 위해 아무 의미 없이 값을 사용할 것을 권장합니다.
위의 예에서는 공백이 남아 있는 "기본 행 번호 지정"의 배리언트를 사용했기 때문에 번호는 enum과 같은 순서로 유지됩니다.
이 버전은 세컨더리 테이블을 사용하는 것보다 빠르지만 코드와 소스 코드의 지식 의존도가 높아집니다.
이 문제를 해결하려면 데이터베이스에 열거 ID가 있는 테이블을 설정할 수도 있습니다.또는 반대로 행을 추가할 때 테이블에서 enum의 ID를 선택합니다.
사이드노트:데이터베이스 테이블에 저장하여 일반 개체로 유지 관리할 필요가 있는 것을 설계하고 있지 않은지 항상 확인하십시오.이 시점에서 새로운 상수를 열거형에 추가해야 한다고 가정할 수 있다면, 이는 일반 개체와 테이블을 대신 만드는 것이 더 나을 수 있음을 나타냅니다.
언급URL : https://stackoverflow.com/questions/229856/ways-to-save-enums-in-database
'programing' 카테고리의 다른 글
Javascript를 사용하여 jquery 로드 여부 확인 (0) | 2022.12.07 |
---|---|
반복하는 동안 목록에서 항목을 제거하려면 어떻게 해야 합니까? (0) | 2022.12.07 |
Java SE API만 사용하는 Java의 단순한 HTTP 서버 (0) | 2022.12.07 |
macOS에서의 my.cnf 파일 위치 (0) | 2022.12.07 |
Google이 JSON 응답 앞에 (1)을 추가하는 이유는 무엇입니까? (0) | 2022.12.07 |