일부 테이블에 대한 데이터베이스에서 보조 기본 키 작성


22

내 테이블 중 일부에 uuid 또는 임의의 긴 키가 될 "second_primary_key"를 추가하고 싶습니다. 일부 테이블의 경우 웹 응용 프로그램에 정수를 노출하고 싶지 않기 때문에 필요합니다. 즉, "/ invoices"페이지에는 송장 목록과 "/ invoices / : id"에 대한 링크가 있습니다. 여기서 : id는 정수입니다. 사용자가 내 시스템의 송장 수를 알기를 원하지 않으므로 "/ invoices / 123"대신 "second_primary_key"를 사용하여 URL이 "/ invoices / N_8Zk241vNa"가되도록합니다.

실제 ID를 숨기고 싶은 다른 테이블도 마찬가지입니다.

이것이 일반적인 관행입니까? 이것을 구현하는 가장 좋은 방법은 무엇입니까?

그리고이 기술은 결국 무엇을 호출하여 검색 할 수 있습니까?


20
정수를 완전히 제거하지 않겠습니까?
larsbe

4
테이블에서 원하는만큼 고유 키 / 인덱스를 정의 할 수 있습니다.
abuzittin gillifirca

2
아마도이를 보조 후보 키라고해야합니다. "기본"은 하나만 제안합니다.
Walter Mitty

4
"제 2 차"는 옥시 모론이다. 기본 키가 있으며 보조 키를 가질 수 있습니다.
중지 해 모니카

7
@RobbieDee 데이터베이스가 완전히 정규화되지 않은 데는 유효한 이유가 있습니다. 또한 후보 또는 보조 키를 갖는 것이 데이터를 정확하게 복제하는 것은 아닙니다.
Machado

답변:


0

UUID 열을 추가 할 수는 있지만 실제로는 필요하지 않습니다. 이것은 프리젠 테이션 레이어 문제입니다. 1999 년뿐만 아니라 $ 1,999의 통화 가치를 저장하는 것을 꿈꾸지 않을 것입니다.

응용 프로그램의 값을 즉시 가리는 방법이 필요합니다. 응용 프로그램 자체 또는 데이터베이스보기에서이 작업을 수행 할 수 있습니다.

우리는 단일 값에 대해서만 이야기하기 때문에 AES 또는 이와 유사한 것과 같은 양방향 암호화를 살펴볼 수 있습니다. 더 가벼울수록 좋습니다.

해싱은 또 다른 가능성이 될 수 있습니다. 해싱은 한 가지 방법이므로 송장 번호를 다시 가져올 지 여부에 따라 다릅니다.


48

"대체 기본 키"는 관계형 데이터베이스 모델링에서 잘 알려진 개념으로, "대체 키"또는 때로는 "보조 키"라고합니다. "잠재적 기본 키"세트를 "후보 키"라고합니다. https://beginnersbook.com/2015/04/alternate-key-in-dbms/를 참조 하십시오

특히 총 레코드 수를 숨기려는 경우이를 구현하는 방법은 전적으로 사용자에게 달려 있습니다. "가장 좋은 방법"은 없습니다. ID를 대 / 소문자를 구분하거나 원하지 않는 경우, 인쇄 된 송장에서 읽을 수있게하려면 허용 또는 유용한 문자 집합, 최대 길이와 같은 요구 사항을 확인해야합니다. 오류없이 전화로 철자를 다시 입력 할 수 있어야합니다.


11
또한 이 시나리오를 설명하는 데 자연 키대리 키라 는 용어를 보았습니다 .
DanK

2
@Dari : 굵은 글씨로 "이 기술은 무엇입니까?" AES 암호 해독 (어쩌면 즉시)이 원하는 종류의 키를 생성하는 경우 사용하면 내 대답과 모순되지 않습니다.
Doc Brown

1
@Dari 앱에 전혀 불필요한 오버 헤드가 발생하기 때문에
Lamak

1
@RobbieDee 우리는 이미 당신이 대체 키를 좋아하지 않는다는 것을 알았습니다. 그러나 그것이 그것들이 쓸모 없다는 것을 의미하지는 않습니다. guid 접근법은 많은 문제를 단순화하기 때문에 좋아합니다.
T. Sar-복원 모니카

1
@RobbieDee 우리는 SQL Server를 사용하지 않습니다. 우리는 MySql을 사용합니다. 누군가가 Prod에서 무언가를 만들었 기 때문에 발생합니다. ID 1234로 말해 봅시다. Dev에서는 당연히 prod보다 더 많은 엔티티를 만듭니다. 1234는 오래 전 테스트를 위해 일부 독립 단체에 의해 촬영되었습니다. prod에서 엔터티를 테스트해야 할 때는 다시 Dev로 마이그레이션해야하며 기본 키는 이미 사용 중입니다. 해당 엔티티에 대한 참조가 guid 기반 인 경우 마이그레이션이 훨씬 쉽습니다. 그러나 최대 절전 모드는 기본 키가 int이거나 길면 훨씬 잘 작동하므로 계속 유지합니다. 내 개발자는 게 으르거나 무지하지 않습니다.
corsiKa

9

대부분의 송장에는 송장 번호가 있으며, 대부분의 회계 규칙에 따라 순차적이거나 회계사가 연도 결과에 서명하지 않거나 IRS (또는 귀하의 국가에서 유사한)가 탭에서 전체 감사를 수행 할 수 있습니다.

사용자는 송장 번호에서 서비스를 제공 한 고객 수 또는 송장의 번호 매기기 전략을 변경하기까지의 시간을 추론 할 수 있습니다.

데이터베이스에 저장된 송장 수는 총 송장 총액의 측정치가 아닙니다. 상공 회의소에 연도 보고서 요청을 포함하여 다른 방법을 찾아 낼 수 있습니다.

그러나 사용자 로그인 화면 뒤에 인보이스를 잠그면 모든 사람이 요청할 수있는 것은 아닙니다. 그런 다음 사용자 로그인시 아약스 방법론을 사용하여 미결제 송장을 요청할 수 있습니다. 이렇게하면 데이터가 보호되고, 아약스로 URL이 숨겨집니다 (아약스 요청의 구성 방법에 대한 세부 정보를 보려고하는 사람은 아무도 없습니다) 데이터를 표시하고 제공하는 방법을 제어합니다.


7
뱅킹 (수표 번호 포함)에 사용되는 일반적인 전략은이 정확한 증가를 위해 1에서 증분 카운트를 시작하지 않고 오히려 더 큰 숫자를 시작하는 것입니다.
DanK

이것이 ID가 이전 기본 키를 대체하는 것이 아니라 추가 기본 키가되는 이유라고 생각합니다.
Alexander

1
나는 그것을 기본 키라고 부르지 않을 것입니다. 나는 이름으로 UUID 슬러그를 갈 것입니다. 그러나 본질적으로 그것은 테이블의 또 다른 색인 필드입니다. ID, 송장 번호 등을 인용하십시오. 필드이지만 기본 키는 아닙니다. 기본 키는 고유해야하며 관계형 매핑을 위해 내부적으로 사용할 수 있습니다. 필드의 색인이 생성 된 경우 where 쿼리를 통해 필드를 빠르게 검색 할 수 있습니다. userXveryY.where ( 'invoice_number', 'foobarbaz10'). get ();
Tschallacka

1
미국의 특성 (필요한 순차적 인보이스 번호, 상공 회의소 보고서)으로 인해 필요하지 않다는 주장으로 기술적 인 질문에 답변하고 있습니다. IMO 이것은 질문에 잘 대답하지 못합니다.
RemcoGerlich

7

이를 위해 hashids 를 사용할 수 있습니다 .이 시나리오를 정확하게 해결하도록 설계되었습니다.

데이터베이스 ID를 짧은 해시 (YouTube 비디오의 URL과 유사)로 인코딩하므로 테이블에 보조 키를 추가 할 필요가 없습니다.


2
이름은 해시가 아니라 가역 기능이므로 다소 오해의 소지가 있습니다. 그러나 문제에 대한 완벽한 해결책 인 것 같습니다.
크레이지 요거트

2
@CrazyYoghurt True ... 그들은 여기에서 한 것처럼 이름을 짓는 이유를 언급했습니다 : hashids.org/#why-hashids
Eric King

3

다른 고유 키를 만들 수 있지만 그렇게해서는 안됩니다. 주어진 이유 때문이 아닙니다. 테이블 크기를 숨기는 간단한 방법이 있습니다.

저장 N_8Zk241vNa비용은 테이블에서 행당 12 바이트, 그리고 인덱스에서 더 많은 비용이 듭니다. 그것은 당신이 필요로하는 것에 꽤 낭비입니다.

정수를 암호화하면 id공간이 필요하지 않으며 런타임에 아무것도 근접하지 않습니다. 사용 방법은 프로그래밍 언어 및 / 또는 데이터베이스에 따라 다릅니다.

AES를 사용하면 128 비트 정수를 얻을 수 있습니다. 이는 base64에서 22자를 의미하며 아마도 원하는 것보다 많을 것입니다. DES 또는 3DES와 같은 블록 크기가 64 인 암호는 원하는대로 11자를 제공합니다.

테이블마다 다른 키를 사용하십시오.

필요한 모든 테이블 크기를 숨기는 경우 모든 테이블에 대해 공통 시퀀스를 사용할 수 있습니다. 여러 테이블에 자주 삽입하는 경우 병목 현상이 발생할 수 있습니다. Hibernate 및 Hi-Lo 알고리즘과 같은 것으로이 문제는 사라집니다.


정확히-다른 값을 숨기기 위해이 값을 저장하는 것은 잘못입니다.
Robbie Dee

이 시나리오에서는 송장 ID가 실제로 기밀이 아니기 때문에 데이터베이스의 관계 구조가 향후 어느 시점에서 데이터를 마스킹해야 할 경우 기밀 두통을 유발하므로 기밀 ID를 사용하는 일반적인 규칙으로 작동 할 수 있습니다. 속성으로 취급하는 것이 좋습니다.
DanK

여기에 aes를 어떻게 적용 할 수 있습니까?
Dari

@Dari 어떻게 AES를 적용 할 있습니까? 당신의 언어를 모른다면 아무도 말할 수 없습니다. 일반적으로 AES는와 함께 작동하며 4 또는 8 바이트로 byte[]쓰고 id고유 한 테이블 번호를 추가하고 암호화 할 수 있습니다 (입력은 정확히 16 바이트 여야 함). 선택할 수있는 모드가 있으면 ECB가 맞습니다.
maaartinus

@DanK 무엇? AES가 안전하지 않다고 주장하고 있습니까? 키를 모르면 공격자가 저장된 속성보다 더 잘 할 수있는 것은 없습니다. 아무것도. +++ 나는 당신의 의견을 이해하지 못한다고 생각합니다.
maaartinus

0

두 개의 다른 기본 키를 작성하는 IMHO는 불가능합니다. 물론 uuid를 DB에 넣어 현재 기본 키의 "별칭"으로 만들 수 있습니다. 고유 제한 조건을 사용하여 해당 컬럼 위에 인덱스를 넣을 수 있지만 기본 키는 본질적으로 단일 테이블 내의 단일 키입니다. 복합 기본 키가있을 수 있지만 원하는 것은 아닙니다.

그래서 나는 거기에 두는 것이 좋지만 색인 만 가지고있는 것이 좋습니다. PK 및 기타 고유 한 열을 기준으로 데이터를 쿼리하기위한 처리 구성 요소를 만들 수 있습니다. "/ invoices / ..."에 대한 요청을 처리 할 때 매개 변수를 확인하십시오. 정수인 경우 ID를 검색하고 그렇지 않으면 uuid를 검색하십시오. 또는 ID 검색에서 아무것도 찾지 못한 경우 UUID 검색을 대체로 사용할 수 있습니다.

그리고 "무작위"UUID를 생성하는 방법에 대해 : "ID를 가져오고, 상수를 추가하고, 16 진수로 변환"과 같은 것이 아닌 이유는 무엇입니까? ID의 고유성은 uuid의 고유성을 제공하고 16 진수는 정상적인 필사자에게는 읽기가 어렵고 상수를 추가하면 00000001과 같은 uuid를 피할 수 있습니다.


1
"ID 확인, 상수 추가, 16 진수로 변환"과 같은 것이 아닌 이유-알아 내기 쉬우므로 URL을 알려주십시오. 그러면 시스템의 다른 모든 인보이스를 살펴볼 것입니다. IMO 문제가 없습니다. 실제로 이것이 해결 될 수있는 가능성
CompuChip

" / 송장에 대한 요청을 처리 할 때"/ ... "단지 매개 변수 확인 - 이 정수의 경우, ID를 검색을 , 그렇지 않으면 UUID 검색 "요점은 (내가 질문을 이해) (ID로 누군가 검색을 방지하는 것입니다 /invoices/123, /invoices/124, ...) URL에서 UUID로만 ​​검색합니다.
TripeHound

또한 모든 16 진 숫자에 문자가 포함되어 있지는 않습니다. 기본 정수와 생성 된 16 진수를 항상 구별하는 것은 불가능합니다.
TRiG

@CompuChip 내가 기대하는대로 컴퓨터에 관심이있다 :-) 그래서 첫눈에 16 진수를 인식합니다. 그러나 Q는 송장 번호가 표시되지 않도록 다른 사람에게 송장 수를 알려주지 않도록 작성되었습니다. 아내, 어머니, 이웃에게 16 진수를 보여 주면 "이상한 텍스트"가 무엇인지 알 수 없습니다. Q 내의 송장 번호에 따른 보안 문제에 대한 통지가있을 경우 해당 목적을위한 복잡한 해싱 방법을 제안합니다.
Jarda

@TripeHound 그는 여전히 내부 또는 일부 액세스 제한 진입 점 내에서 ID로 검색 할 수 있습니다 ...
Jarda

0

두 키가 같은 사실을 가리키면 결코 충돌하지 않습니다. 원래 키의 사용자 지정 해시 코드를 생성하는 스칼라 함수를 사용하여 원래 키에서 다른 키를 파생시키지 마십시오.

또는 두 버전의 키를 모두 저장하는 부록 매핑 테이블을 만들 수 있습니다. 이 테이블은 보조 키를 조회하기위한 사전 역할을합니다.

내 이해에 따르면 키는 암시 적 인덱스이며 인덱스를 많이 추가할수록 삽입 속도가 느려집니다.


+1 그렇습니다. 잠재적으로 인덱스가있는 큰 문자열 열을 추가하는 것은 다른 사람들이 제안하는 무가치 작업이 아닙니다. 인덱스가 추가되면 스토리지 오버 헤드가 줄어들면서 삽입 속도가 저하되기 시작합니다.
Robbie Dee

0

특정 사용 사례에 대한 또 다른 접근 방법은 데이터베이스와 응용 프로그램을 수정하는 대신 송장에 대한 사용자 지정 경로를 만들어서 / invoices / : f (id) 여기서 f (id)가 id의 일부 기능이라는 것입니다.

사용자 정의 경로는 요청을 올바른 조치 서버 측에 맵핑해야합니다.


0

'대체 키'(AK)라고도하는 완전히 허용되는 방법입니다. 기본적으로 AK는 다른 고유 인덱스 또는 고유 제약 조건입니다.

AK를 기반으로 외래 키 제약 조건을 만들 수도 있습니다.

가능한 유스 케이스는 설명과 같습니다. 계속 증가하는 ID 번호에 클러스터 된 PK가 있지만 간단히 추측 할 수 있기 때문에이 번호가 검색 기준으로 표시되거나 사용되기를 원하지 않습니다. 또한 AK로 임의의 고유 식별자 또는 참조 번호가 있으며 이는 사용자에게 제시 한 ID입니다.


0

여러 종류의 키 / 인덱스가 있습니다. 기본 키는 특별한 고유 인덱스이며, 답변에 따르면 다른 고유 키를 만들 수 있습니다. 그리고 정당한 사유가없는 한 데이터베이스 내부를 공개하지 않는 것이 가장 좋습니다.

이 질문은 송장 및 번호와 관련되어 있으므로 회계 업계에서 송장 번호가 어떻게 보이는지 조사하는 것이 좋습니다. http://smallbusiness.chron.com/assign-invoice-numbers-52422.html

기본 키인 내부 ID가 있고 응용 프로그램 / 고객이 볼 수있는 송장 번호가있는 다른 고유 한 필드를 갖는 것이 지저분 해 보일 수 있습니다. 그러나 고객이 새로운 인보이스 번호 매기기 체계를 채택하려고한다고 할 때 그리 불쾌하지 않습니다. 이 경우 왁스의 전체 공의 번호를 다시 매기기 위해 다른 테이블의 내부 ID와의 관계를 방해하지 않습니다. 내부 ID는 그대로 유지하고 비 내장 송장 번호를 다시 매 깁니다.

이상적으로는 변경 될 가능성이있는 키 / 외부 키에 테이블을 묶지 않고 내부 테이블과 관계를 앱 계층에 투명하게 유지하려고 노력합니다.


0

해봐

이는 블로그 기사 등이 자주 사용하는 "슬러그"필드와 다르지 않습니다. URL에서 사용하기에 적합한 기본 키와 별도로 데이터베이스 레코드를 참조하는 고유 한 방법입니다. 나는 누군가가 그것에 대해 논쟁하는 것을들은 적이 없다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.