데이터를 저장하는 가장 좋은(무료) 방법은 무엇입니까?파일 시스템 업데이트는 어떻습니까?

StackOverflow https://stackoverflow.com/questions/142114

  •  02-07-2019
  •  | 
  •  

문제

이 문제를 해결하는 방법에 대한 아이디어가 있지만 내 문제에 더 쉽고 확장 가능한 것이 있는지 알고 싶었습니다.

제가 작업 중인 프로그램에는 두 가지 기본 형태의 데이터가 있습니다.이미지 및 해당 이미지와 관련된 정보.이미지와 관련된 정보는 이전에 극도로 단순한 JET 데이터베이스(테이블 4개)에 저장되어 저장 필드가 느리고 불완전한 것으로 나타났습니다.우리는 데이터 스토리지의 새로운 구현으로 전환하고 있습니다.관련된 데이터 구조의 단순성을 고려하면 데이터베이스가 과도하다고 생각했습니다.

각 이미지는 그 자체의 정보(캡처 매개변수)를 갖고, 상호 연관된 이미지 그룹의 일부가 되며(예를 들어 동일한 30분 동안 촬영됨), 더 큰 그룹의 일부가 됩니다(동일한 사람이 촬영됨). ).지금은 고유 식별자가 있는 사전에 사람을 저장하고 있습니다.그러면 각 사람은 서로 다른 사진 그룹의 목록을 갖고, 각 사진 그룹에는 사진 목록이 있습니다.이러한 클래스는 모두 직렬화 가능하며 사전을 직렬화 및 역직렬화할 뿐입니다.상당히 간단한 내용입니다.이미지는 별도로 저장되므로 사전의 크기가 천문학적으로 커지지 않습니다.

문제는:새로운 정보 필드를 추가해야 하면 어떻게 되나요?잠재적인 향후 개정을 설명하기 위해 이러한 데이터 구조를 설정하는 쉬운 방법이 있습니까?과거에 C에서 이 문제를 처리한 방식은 향후 확장성을 위해 많은 빈 바이트(적어도 k)가 있는 직렬화 가능한 구조체를 생성하는 것이었고 구조체의 바이트 중 하나는 버전을 나타내는 것이었습니다.그런 다음 프로그램이 구조체를 읽을 때 대규모 스위치 문을 기반으로 어떤 역직렬화를 사용할지 알 수 있습니다(그리고 외부 데이터가 무시되는 필드로 들어가기 때문에 이전 버전에서는 새 데이터를 읽을 수 있습니다).

C#에 그러한 체계가 존재합니까?예를 들어, String 및 Int 개체 그룹인 클래스가 있고 다른 String 개체를 구조체에 추가하는 경우 디스크에서 개체를 역직렬화한 다음 문자열을 여기에 추가하려면 어떻게 해야 합니까?여러 버전의 데이터 클래스와 역직렬화 스트림을 사용하고 기본 클래스에 저장된 일부 버전 정보를 기반으로 역직렬화를 처리하는 팩토리를 보유해야 합니까?아니면 디스크의 모든 필드를 자동으로 역직렬화하고 새 필드가 추가된 경우 예외를 포착하고 해당 값을 빈 문자열 및 정수로 대체할 수 있기 때문에 이러한 종류의 정보를 저장하는 데 사전과 같은 클래스가 이상적인가요?

사전 접근 방식을 사용하면 파일 읽기/쓰기 및 매개변수 검색 시간과 관련된 속도 저하가 있습니까?클래스에 필드만 있으면 필드 검색은 즉시 이루어지지만 사전에서는 해당 클래스와 관련된 약간의 오버헤드가 있다고 생각합니다.

감사해요!

도움이 되었습니까?

해결책

내 뇌가 현재 튀겨져서 데이터베이스에 대해 조언하거나 반대 할 수는 없지만 버전에 대한 직렬화를 찾고 있다면 적어도 체크인하지 않는 바보가 될 것입니다. 프로토콜 버퍼.

다음은 C#/. Net에 대해 알고있는 빠른 구현 목록입니다.

다른 팁

sqlite 당신이 원하는 것입니다. 대부분의 언어에 바인딩을하는 빠르고 내장 가능한 단일 파일 데이터베이스입니다.

확장 성과 관련하여 기본 속성이있는 모델을 저장 한 다음 향후 변경 사항에 대한 속성 확장에 대한 별도의 테이블을 가질 수 있습니다.

1 년 또는 2 년이 지나면 코드가 아직 사용중인 경우 1) 다른 개발자가 코드를 유지하기 위해 사용자 정의 된 코드 구조를 배울 필요가 없다는 것을 기쁘게 생각합니다. 2) 내보내기,보기, 수정할 수 있습니다. 표준 데이터베이스 도구 (SQLITE 파일 및 다양한 쿼리 도구 용 ODBC 드라이버가있는 데이터) 및 3) 최소한의 코드 변경으로 데이터베이스로 확장 할 수 있습니다.

단지 경고의 단어, sqllite, 프로토콜 버퍼, Mmap et al ... 모두 매우 좋지만 각 구현 프로토 타입과 테스트를해야하며 동일한 성능 문제 나 다른 병목 현상에 도달하지 않아야합니다.

단순성은 단지 SQL (Express)로 향상 될 수 있으며 (Perf Gain에 놀랄 수 있음) 현재 데이터베이스 설계에서 누락 된 내용을 수정할 수 있습니다. Perf가 여전히 문제라면 이러한 다른 기술을 조사하기 시작하십시오.

이런 종류의 상황을 처리할 수 있는 이름이 기억나지 않는 데이터베이스 스키마가 있습니다.기본적으로 두 개의 테이블이 있습니다.한 테이블은 변수 이름을 저장하고 다른 테이블은 변수 값을 저장합니다.변수를 그룹화하려면 변수 이름 테이블과 일대다 관계를 갖는 세 번째 테이블을 추가하십시오.이 설정은 데이터베이스 스키마를 계속 변경하지 않고도 다양한 변수를 계속 추가할 수 있다는 장점이 있습니다.마케팅과 같이 마음이 자주 바뀌는 부서를 상대할 때 베이컨을 꽤 많이 절약했습니다.

유일한 단점은 변수 값 테이블이 실제 값을 문자열 열(실제로는 varchar 또는 nvarchar)로 저장해야 한다는 것입니다.그런 다음 값을 다시 기본 표현으로 변환하는 번거로움을 처리해야 합니다.나는 현재 이와 같은 것을 유지하고 있습니다.변수 테이블에는 현재 약 8억 개의 행이 있습니다.여전히 1초 이내에 특정 값의 변형을 검색할 수 있으므로 상당히 빠릅니다.

저는 C# 프로그래머는 아니지만 mmap() 호출을 좋아하고 C#에 대해 그러한 작업을 수행하는 프로젝트가 있다는 것을 알았습니다.

보다 Mmap

구조화된 파일은 특정 애플리케이션에 맞게 조정된 경우 성능이 매우 뛰어나지만 관리하기 어렵고 코드 리소스를 거의 재사용할 수 없습니다.더 나은 솔루션은 가상 메모리와 유사한 구현입니다.

  • 최대 4GB의 정보를 관리할 수 있습니다.
  • 실제 데이터 크기에 맞게 공간을 최적화할 수 있습니다.
  • 모든 데이터는 단일 배열로 볼 수 있으며 읽기/쓰기 작업을 통해 액세스할 수 있습니다.
  • 저장하기 위해 구조화할 필요가 없으며 그냥 사용하고 저장하면 됩니다.
  • 캐시될 수 있습니다.재사용성이 높습니다.

그러니 다음과 같은 이유로 sqllite와 함께 가십시오.
1. 매번 디스크에서 전체 데이터베이스를 읽거나 쓸 필요가 없습니다.
2. 처음에 자리 표시자를 남기지 않더라도 추가하기가 훨씬 쉽습니다.
3. 원하는 것을 기준으로 쉽게 검색 할 수 있습니다
4. 응용 프로그램 이외의 방식으로 데이터를 변경하기 쉽습니다.

사전 접근법 문제
1. 스마트 사전을 만들지 않는 한 매번 전체 데이터베이스를 읽고 쓰야합니다 (데이터 구조를 신중하게 설계하지 않는 한 거꾸로 호환성을 유지하기가 매우 어렵습니다).
---- a) 당신이 충분한 장소 홀더를 떠나지 않았다면 안녕
2. 캡처 속성 중 하나를 검색하기 위해 모든 사진을 통해 선형 검색 해야하는 것처럼 보입니다.
3. 그림이 둘 이상의 그룹에있을 수 있습니까? 사진이 한 명 이상의 사람에 걸릴 수 있습니까? 두 사람이 같은 그룹에있을 수 있습니까? 사전과 함께 이러한 것들은 털이 될 수 있습니다 ....

데이터베이스 테이블을 사용하면 새 속성을 얻으면 Alter Table Picture Add Attribute Datatype이라고 말할 수 있습니다. 그런 다음 속성에 값이 있어야한다는 규칙을하지 않는 한 여전히 이전 버전을로드하고 저장할 수 있습니다. 동시에 최신 버전은 새로운 속성을 사용할 수 있습니다.

또한 데이터베이스에 사진을 저장할 필요가 없습니다. 데이터베이스에 그림의 경로를 저장할 수 있습니다. 그런 다음 앱에 사진이 필요하면 디스크 파일에서 사진을로드하십시오. 이것은 데이터베이스 크기를 더 작게 유지합니다. 또한 디스크 파일을 얻기위한 여분의 찾기 시간은 이미지를로드하는 시간에 비해 중요하지 않을 것입니다.

아마도 당신의 테이블이 될 것입니다
Picture (PictureId, GroupId?, 파일 경로, 캡처 매개 변수 1, 캡처 매개 변수 2 등 ..)

더 많은 유연성을 원한다면 테이블 캡처 파라미터 (PictureId, ParameterName, Parametervalue)를 만들 수 있습니다 ... 단지 하나의 테이블에 넣는 것보다 훨씬 덜 효율적이기 때문에 (검색/검색을위한 쿼리는 말할 것도 없습니다. 캡처 매개 변수가 더 복잡합니다).

사람 (PersonId, 이름/등과 같은 사람 속성)
그룹 (GroupId, Group Name, PersonId?)
persongroup? (personid, groupid)
PictureGroup? (GroupId, PictureId)

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