문제

문제 설명: 내 지원서에서는 데이터 패킷의 내용을 특정 형식으로 표시해야 합니다.예:

압축된 바이너리 데이터. 예:4바이트 헤더, 4바이트 유형(미리 정의된 의미를 갖는 유형 코드), 소스 주소, 대상 주소 등입니다.

이전에는 데이터를 바이너리 파일에 저장하는 집에서 만든 구현을 만들었지만(고정 레코드 길이로 빠른 조회가 가능함) 시간이 지나면서 일종의 데이터베이스를 발명하고 있다는 것을 깨달았습니다.예를 들어, 저는 매우 큰 데이터 파일을 위한 효율적인 바이너리 저장소 형식을 구현하고 있습니다.또한 일부 필드에 대한 검색을 빠르게 실행하기 위해 자체 색인 생성을 구현하고 있습니다.나는 실제 DB(간단한 SQLite라도)가 이 작업을 투명하게 단순하게 만들 수 있다고 생각합니다.

질문 1: DB는 그러한 데이터를 저장하는 데 유용하며 어떻게 수행해야 합니까?여기에는 일대다, 다대다 매핑 및 기타 고급 기능이 없습니다. 이는 사용자에게 표시하고 사용자가 상호 작용할 수 있도록 하고 싶은 특정 내부 구조를 가진 단순한 패킷 시퀀스일 뿐입니다.특정 필드로 검색).

질문 #2: 이제 사용자가 자신의 패킷 형식을 지정할 수 있다고 가정합니다.구성 파일에서:각 필드의 길이, 해당 유형, 해당 값의 의미(열거의 경우) 등.이를 위해 DB 지원 구현을 어떻게 확장합니까?사용자가 DB 스키마를 정의해야 합니까?구성 파일을 이 스키마로 자동 변환해야 합니까?ORM?

질문 #3: 더욱 발전된...이제 데이터 패키지의 길이와 내용이 다양할 수 있다고 가정합니다.즉, 유형 #2 패키지에는 일부 필드가 있고, 유형 #3에는 일부 다른 필드 등이 있습니다.하지만 나는 여전히 내 앱이 이를 처리하여 모든 것을 훌륭하게 표시하고 사용자가 구성 파일에서 형식을 지정할 수 있도록 허용하고 싶습니다.어떻게 이루어 집니까?

미리 감사드립니다.

도움이 되었습니까?

해결책

질문 #1 : DBS는 그러한 데이터를 저장하는 데 유용하며 어떻게해야합니까?

확실히 데이터베이스는이 응용 프로그램에 유용합니다. 자신의 특수 목적 데이터 저장소를 구현할 수 있으며, 해당 전문화를 위해 설계 할 수 있기 때문에 특정 응용 프로그램에 더 효율적일 수 있습니다. 관계형 데이터베이스는 일반적인 목적이지만 데이터베이스를 사용하여 몇 주 또는 몇 달의 개발 시간을 피할 수 있습니다.

나는 오늘 초에 또 다른 질문에 대답했다. 각각의 새로운 하위 유형은 고유 한 특성 세트를 가지고있는 확장 가능한 유형을 처리하는 방법에 대해 또 다른 질문에 대답했다.

"제품 테이블, 많은 종류의 제품, 각 제품에는 많은 매개 변수가 있습니다.."

귀하의 신청서를 위해 나는 선택할 것입니다 콘크리트 테이블 상속 설계.

질문 #2 : 이제 사용자가 자신의 패킷의 형식, 즉 구성 파일의 형식을 지정할 수 있다고 가정합니다 : 각 필드의 길이, 유형, 그 값의 의미 (열거의 경우) 등. 이를 위해 DB 지원 구현을 어떻게 확장합니까?

패킷 유형의 수가 상대적으로 적고 많은 패킷이 거의 동일한 구조로 삽입됩니다. 따라서 데이터베이스의 메타 데이터 관리 기능을 사용해야합니다. 각각의 새로운 패킷 유형에 대해 추가 테이블을 정의합니다.

패킷의 각 필드는 별도의 데이터베이스 열에 저장됩니다. 이렇게하면 효율적인 검색을 지원하기 위해 각 열을 개별적으로 색인화 할 수 있습니다.

일부 필드가 필수되도록 제약 조건을 정의 할 수도 있습니다 (NOT NULL) 또는 조회 테이블로 제한된 값. 다시 말하지만, 데이터베이스의 기능을 활용하여 메타 데이터를 사용하여 바람직한 일관된 구조를 시행합니다.

SQL은 이미 데이터 유형, 제약 조건이있는 필드를 지정하기위한 표준 선언 언어를 지원합니다. 왜 다른 언어를 개발 한 다음 SQL로 번역해야합니까?

질문 #3 : 더욱 진보 된 ... 이제 데이터 패키지가 길이와 내용이 다양 할 수 있다고 가정합니다.

주어진 패킷 유형에서 선택 사항 인 필드는 허용해야합니다. NULL 해당 열에서.

다른 팁

간단한 규칙은 이것입니다. 데이터를 쿼리하려면 DB 내의 테이블 내 이산 필드 여야합니다. 그렇지 않다면, 당신은 blob을 저장하고 그것을 끝낼 수 있습니다.

즉, 블로브에서 "메타 데이터"를 도출하고 색인하려면 쉽게 할 수 있습니다.

데이터 유형이 데이터베이스가 지원할 수있는 내용 (또는 정확하게 변환 될 수 있음)과 일치하는 경우 DB 열에 잘 매핑되는 구성 요소 부품에 블로브가 폭발 할 수 있습니다.

"즉시 테이블"을 정의하는 문제 (쉽게 수행 할 수 있음)는 테이블의 정의가 아니라 테이블의 잠재적 변화입니다. 변경되는 테이블 (즉, 추가 또는 삭제 된 열)은 변경 기간 동안 사용할 수없는 경향이 있습니다. 100 행의 문제는 아닙니다. 수백만 행에 대한 실제 문제.

데이터 정의가 상당히 정적 인 경우 사용자가 블로브를 설명 할 수있는 매핑 기능을 작성한 다음 해당 정의를 사용하여 호환 테이블을 작성하고 가져 오기 중에 블로브를 적절하게 변환합니다.

"다른 유형의 다른 행"에 관해서는, 그 데이터를 단일 테이블에 넣을 수 있습니다. 일부 행에는 다른 행에 "사용하지 않은"열이 있으며, 각 행은 다른 행에 유형별로 식별됩니다. 행 정의가 많고 차이가 많으면이 작업을 수행하는 낭비 된 공간이 많이 나옵니다. 그런 다음 각 행 유형에 대한 테이블과 행 유형을 보유하고 실제 테이블의 실제 행을 참조하는 마스터 테이블을 가지고 갈 수 있습니다. 원래 데이터 패킷의 관계에 관심이있는 경우에만이 마스터 테이블이 필요합니다 (그러면 영수증 순서, 예를 들어 보관할 수 있습니다).

실제로, 그것은 당신이 가지고있는 데이터의 양, 당신이 기대하는 양, 당신이하고 싶은 일의 양과 이미 얼마나 많은 일을하고 싶은지, 당신이 이미 수행 한 금액 등으로 요약됩니다.

당신이 고려하고 싶은 또 다른 옵션은입니다 버클리 DB 또는 클론 중 하나. BDB는 매우 낮은 레벨이며 SQL이 없습니다. 정말 작고 빠른 파일 지원 해시 테이블입니다. 그것은 영원히 주변에 있었고, 속도와 단순성이 가장 중요한 곳에서 사용됩니다. 하지만 달성하려는 작업을 수행하려면 기능을 추가해야합니다.

일대다 관계가 없다고 말씀하셨음에도 불구하고, 그렇습니다. :)

패킷 저장을 위해 두 개의 테이블을 만드는 것이 좋습니다.하나는 패킷에 공통적인 "헤더" 또는 "스칼라" 정보를 저장하는 것입니다. 이는 어떤 데이터가 존재하는지 정의할 수 있지만 패킷에 저장된 실제 데이터는 아닙니다.

두 번째 테이블은 각 패킷에 대한 데이터를 저장하며 각 필드-값 조합은 이 테이블의 행을 나타냅니다.예를 들어 다음 두 테이블은 다음과 같습니다.

create table packet
(
    packet_id int identity(1, 1) primary key,
    destination varchar(50),
    sender varchar(50),
    packet_type_id int not null
)

create table packet_field
(
    packet_field_id int identity(1, 1) primary key,
    packet_id int not null references packet (packet_id),
    field_id int not null,
    data varbinary(500)
)

분명히 이 두 테이블은 저장되는 데이터의 유형과 크기에 대해 가정하고 있으며 저장해야 하는 데이터를 모두 포함하지는 않습니다.그러나 이 기본 구조는 동적으로 정의된 패킷 형식을 허용하며 쉽게 색인화되는 스키마입니다(예: packet_id+field_id ~에 packet_field 생각할 필요도 없을 것입니다).

그런 다음 모든 애플리케이션이 담당하는 것은 패킷의 압축을 풀고 이를 이 스키마의 DB에 저장한 다음 (필요한 경우) 다시 압축하는 것입니다.

물론 이 시점부터는 패킷의 실제 형식을 저장하는 테이블이 필요합니다.뭔가...

create table packet_type
(
    packet_type_id int identity(1, 1) primary key,
    name varchar(200) not null
)

create table packet_type_field
(
    field_id int identity(1, 1) primary key,
    packet_type_id int not null references packet_type (packet_type_id)
    field_offset int not null,
    name varchar(200) not null
)

다시 말하지만, 분명히 단순화되었지만 기본 아이디어를 보여줍니다.당신은 하나의 기록을 갖게 될 것입니다 packet_type 각 패킷 형식에 대한 테이블과 packet_type_field 주어진 패킷의 각 필드에 대해.이는 임의의 바이너리 데이터 청크를 앞서 언급한 패킷 저장 스키마로 처리하는 데 필요한 대부분의 정보를 제공합니다.

세 가지 방법이 떠 오릅니다.

SFLOW 및 IPFLOW는 제한된 패킷 컨텐츠 세트를 전송할 수 있습니다. 여러 데이터베이스에 직접 로그인 할 수 있습니다.

또 다른 대상 방법은 소스 또는 대상 주소와 같은 매우 간단한 코골이 규칙을 쓰는 것입니다. 그런 다음 패킷의 페이로드를 코를 캡처해야합니다. 그렇게하면 필요한 실제 데이터 만 얻을 수 있습니다. 예를 들어 패킷 내부의 데이터 필드 만 가져올 수 있습니다. 예 : 비밀번호 등

NGREP는 또한 선택적 데이터를 전선에서 바로 가져올 수 있습니다.

물론 서버/워크 스테이션 자체에서 캡처를하지 않으면 포트에서 탭 또는 모니터 세션이 필요할 수 있습니다.

이 구현의 열렬한 팬은 아니지만, 우리는 본질적으로 일부 호출 목록을 위해이를 수행하는 소프트웨어가 있습니다. 본질적으로 여기에 그들이하는 일이 있습니다.

  1. 열 정의가있는 테이블 - tblcolumndefs라고 부릅니다. 이 테이블에는 "이름", "유형", "길이"및 "설명"과 같은 열이 포함되어 있습니다.
  2. 인스턴스 마스터 테이블 (tblpacketNames). 기본적으로 정의하는 각 패킷 유형에 대해 "PacketTypeid", "PacketName"및 "Description"만
  3. 인스턴스 정의 테이블 (이것은 당신을 위해 tblpacketcolumns입니다). 이 테이블은 사전 정의 된 열을 모아 저장하는 데이터 구조를 형성합니다. 예를 들어 "PacketTypeid", "columnNumber", "ColumnId"를 유지할 수 있습니다. 데이터베이스-정규화 스피크에서, 이것은 열을 사용하는 패킷에 열을 매핑하기 때문에 다수의 테이블입니다.
  4. 두 번째 데이터베이스 (이 단계의 동적 SQL/주입 시사로 인해)에서 테이블은 실제 데이터를 유지하기 위해 동적으로 만들어집니다. 예를 들어, "Ping"이라는 패킷 유형을 정의 한 경우 데이터베이스에 "Ping"이라는 테이블이 해당 데이터를 보유 할 수 있습니다. tblcolumndefs에 연결된 tblpacketcolumns를 사용하여 어떤 필드 유형을 만들고 얼마나 큰지 알아냅니다. 1 단계의 열을 사용하여 3 단계의 패킷 유형 정의와 일치하는 테이블 모음이 끝납니다.

참고 : 단계 4의 SQL 주입 시사점은 특히 그렇지 않습니다. 테이블을 동적으로 동적으로 만들 수 있으며 보안이 올바르게 설계되지 않았고 응용 프로그램의 사용자가 제공 한 필드의 입력이 올바르게 정리되지 않으면 일부 결과를 초래할 수 있습니다. 특히이 응용 프로그램에 신뢰할 수없는 발신자 (예 : 인터넷)가 사용할 수있는 인터페이스가있는 경우.

이것을 사용하면 테이블을 만들 때 원하는 인덱스를 만들 수 있습니다 (1 단계의 열이 특정 열을 "색인 가능"으로 표시하고 테이블을 만들 때 인덱스가 생성됩니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top