문제

삽입이 간단하도록 연결 목록을 mysql 데이터베이스에 저장하는 가장 좋은 방법은 무엇입니까(예:매번 많은 항목을 다시 색인화할 필요가 없으며 목록을 순서대로 쉽게 꺼낼 수 있습니다.

도움이 되었습니까?

해결책

'position'이라는 테이블에 정수 열을 저장합니다.목록의 첫 번째 항목에는 0을 기록하고 두 번째 항목에는 1을 기록합니다.데이터베이스에서 해당 열을 색인화하고 값을 가져오려면 해당 열을 기준으로 정렬하세요.

 alter table linked_list add column position integer not null default 0;
 alter table linked_list add index position_index (position);
 select * from linked_list order by position;

인덱스 3에 값을 삽입하려면 행 3 이상의 위치를 ​​수정한 후 다음을 삽입하세요.

 update linked_list set position = position + 1 where position >= 3;
 insert into linked_list (my_value, position) values ("new value", 3); 

다른 팁

Adrian의 솔루션을 사용하지만 1씩 증가하는 대신 10 또는 100씩 증가합니다.그런 다음 삽입 아래의 모든 항목을 업데이트하지 않고도 삽입하는 항목의 차이의 절반으로 삽입을 계산할 수 있습니다.평균 삽입 횟수를 처리할 수 있을 만큼 큰 숫자를 선택하세요. 숫자가 너무 작으면 삽입 중에 더 높은 위치로 모든 행을 업데이트해야 합니다.

두 개의 자체 참조 열 PreviousID 및 NextID가 있는 테이블을 만듭니다.항목이 목록의 첫 번째 항목인 경우 PreviousID는 null이 되고, 마지막 항목인 경우 NextID는 null이 됩니다.SQL은 다음과 같습니다.

create table tblDummy
{
     PKColumn     int     not null, 
     PreviousID     int     null, 
     DataColumn1     varchar(50)     not null, 
     DataColumn2     varchar(50)     not null,  
     DataColumn3     varchar(50)     not null, 
     DataColumn4     varchar(50)     not null, 
     DataColumn5     varchar(50)     not null, 
     DataColumn6     varchar(50)     not null, 
     DataColumn7     varchar(50)     not null, 
     NextID     int     null
}

연결된 목록은 테이블의 재귀 포인터를 사용하여 저장할 수 있습니다.이는 Sql에 저장되는 계층 구조와 거의 동일하며 재귀 연관 패턴을 사용합니다.

그것에 대해 더 자세히 알아볼 수 있습니다. 여기.

이게 도움이 되길 바란다.

가장 간단한 옵션은 목록 항목당 행, 항목 위치에 대한 열, 항목의 다른 데이터에 대한 열이 있는 테이블을 만드는 것입니다.그런 다음 위치 열에서 ORDER BY를 사용하여 원하는 순서로 검색할 수 있습니다.

create table linked_list
(   list_id   integer not null
,   position  integer not null 
,   data      varchar(100) not null
);
alter table linked_list add primary key ( list_id, position );

목록을 조작하려면 위치를 업데이트한 다음 필요에 따라 레코드를 삽입/삭제하면 됩니다.따라서 목록 1의 인덱스 3에 항목을 삽입하려면 다음을 수행하세요.

begin transaction;

update linked_list set position = position + 1 where position >= 3 and list_id = 1;

insert into linked_list (list_id, position, data)
values (1, 3, "some data");

commit;

목록에 대한 작업에는 여러 명령이 필요할 수 있으므로(예: 삽입에는 INSERT 및 UPDATE가 필요함) 항상 트랜잭션 내에서 명령을 수행해야 합니다.

이 간단한 옵션의 변형은 각 항목에 대해 일부 요소(예: 100)만큼 위치를 증가시켜 INSERT를 수행할 때 항상 다음 요소의 위치 번호를 다시 매길 필요가 없도록 하는 것입니다.그러나 다음 요소를 언제 증가시켜야 하는지 알아내려면 약간의 노력이 필요하므로 삽입이 많을 경우 단순성은 떨어지지만 성능은 향상됩니다.

요구 사항에 따라 다음과 같은 다른 옵션이 매력적일 수 있습니다.

  • 목록에서 많은 조작을 수행하고 검색을 많이 수행하지 않으려면 위치 열을 사용하는 대신 목록의 다음 항목을 가리키는 ID 열을 사용하는 것이 좋습니다.그런 다음 항목을 순서대로 가져오려면 목록 검색 시 논리를 반복해야 합니다.이는 저장된 proc에서 비교적 쉽게 구현할 수 있습니다.

  • 목록이 많고 목록을 텍스트/이진으로 직렬화 및 역직렬화하는 빠른 방법이며 전체 목록만 저장하고 검색하려는 경우 전체 목록을 단일 열에 단일 값으로 저장합니다.아마도 당신이 여기서 요구하는 것은 아닐 것입니다.

이 게시물은 오래되었지만 여전히 .02$를 제공할 예정입니다.테이블이나 레코드 세트의 모든 레코드를 업데이트하는 것은 순서를 해결하기에는 이상하게 들립니다.인덱싱의 양도 엄청나게 많았지만 대부분이 이를 받아들인 것 같습니다.

업데이트와 인덱싱을 줄이기 위해 내가 생각해낸 미친 해결책은 두 개의 테이블을 만드는 것입니다. (대부분의 경우 어쨌든 모든 레코드를 하나의 테이블에 정렬합니다.)정렬 중인 목록의 레코드를 보유하는 테이블 A와 순서 레코드를 문자열로 그룹화하여 보유하는 테이블 B입니다.순서 문자열은 웹 서버 또는 웹 페이지 애플리케이션의 브라우저 계층에서 선택한 레코드를 정렬하는 데 사용할 수 있는 배열을 나타냅니다.

Create Table A{
Id int primary key identity(1,1),
Data varchar(10) not null
B_Id int
}

Create Table B{
Id int primary key Identity(1,1),
GroupName varchat(10) not null,
Order varchar(max) null
}

주문 문자열의 형식은 ID, 위치 및 문자열을 분할()할 구분 ​​기호여야 합니다.jQuery UI의 경우 .sortable('serialize') 함수는 목록에 있는 각 레코드의 ID와 위치를 포함하는 POST 친화적인 주문 문자열을 출력합니다.

진짜 마법은 저장된 순서 문자열을 사용하여 선택한 목록을 다시 정렬하도록 선택하는 방식입니다.이는 구축 중인 애플리케이션에 따라 다릅니다.다음은 항목 목록을 재정렬하는 jQuery의 예입니다. http://ovisdevelopment.com/oramincite/?p=155

https://dba.stackexchange.com/questions/46238/linked-list-in-sql-and-trees 빠른 삽입과 정렬을 위해 부동 소수점 위치 열을 사용하는 방법을 제안합니다.

또한 특수한 SQL Server 2014에 대해서도 언급합니다. 계층 ID 특징.

제가 바로 생각할 수 있는 몇 가지 접근 방식이 있는데, 각각의 접근 방식은 복잡성과 유연성의 수준이 다릅니다.귀하의 목표는 실제 연결 목록으로 저장을 요구하는 것이 아니라 검색 순서를 유지하는 것이라고 가정합니다.

가장 간단한 방법은 테이블의 각 레코드에 순서 값을 할당하는 것입니다(예:1, 2, 3, ...).그런 다음 레코드를 검색할 때 순서 열에 order-by를 지정하여 다시 순서대로 가져옵니다.

또한 이 접근 방식을 사용하면 목록의 구성원 여부에 관계없이 레코드를 검색할 수 있지만 하나의 목록에만 구성원이 있을 수 있으며 레코드가 속한 목록을 나타내기 위해 추가 "목록 ID" 열이 필요할 수 있습니다.

약간 더 정교하면서도 더 유연한 접근 방식은 멤버십에 대한 정보를 목록에 저장하거나 목록을 별도의 테이블에 저장하는 것입니다.테이블에는 3개의 열이 필요합니다.목록 ID, 서수 값 및 데이터 레코드에 대한 외래 키 포인터입니다.이 접근 방식에서 기본 데이터는 목록의 구성원에 대해 전혀 알지 못하며 여러 목록에 쉽게 포함될 수 있습니다.

생성된 열을 추가하는 것이 훨씬 간단하다고 생각합니다. Datetime 유형 및 위치 열 int, 이제 중복된 위치를 가질 수 있습니다. select 문에서 order by 위치, 설명 옵션이 생성되고 목록이 순서대로 가져옵니다.

이것은 제가 한동안 스스로 알아내려고 노력해왔던 것입니다.지금까지 내가 찾은 가장 좋은 방법은 다음 형식(의사 코드)을 사용하여 연결된 목록에 대한 단일 테이블을 만드는 것입니다.

링크드리스트(

  • 키1,
  • 정보,
  • 키2

)

key1이 시작점입니다.Key2는 다음 열에서 자체적으로 연결되는 외래 키입니다.따라서 귀하의 열은 다음과 같은 링크를 연결합니다.

열 1

  • 키1 = 0,
  • 정보 = '안녕하세요'
  • 키2 = 1

Key1은 col1의 기본 키입니다.key2는 col2의 key1로 이어지는 외래 키입니다.

col2

  • 키1 = 1,
  • 정보= '안녕하세요'
  • 키2 = null

col2의 key2는 아무 것도 가리키지 않기 때문에 null로 설정됩니다.

테이블에 대한 열을 처음 입력할 때 key2가 null로 설정되어 있는지 확인해야 합니다. 그렇지 않으면 오류가 발생합니다.두 번째 열을 입력한 후 다시 돌아가서 첫 번째 열의 key2를 두 번째 열의 기본 키로 설정할 수 있습니다.

이는 한 번에 많은 항목을 입력한 다음 돌아가서 적절하게 외래 키를 설정하는 가장 좋은 방법입니다(또는 이를 수행하는 GUI를 구축).

제가 준비한 실제 코드는 다음과 같습니다(실제 코드는 모두 MSSQL에서 작동했습니다.사용 중인 SQL 버전에 대해 조사해 볼 수도 있습니다!):

createtable.sql

create table linkedlist00 (

key1 int primary key not null identity(1,1),

info varchar(10),

key2 int

)

Register_foreign_key.sql

alter table dbo.linkedlist00

add foreign key (key2) references dbo.linkedlist00(key1)

*두 단계로 이루어져야 하기 때문에 두 개의 별도 파일에 넣었습니다.MSSQL에서는 참조할 외래 키에 대한 테이블이 아직 존재하지 않기 때문에 이를 한 단계로 수행할 수 없습니다.

Linked List는 특히 다음과 같은 경우에 강력합니다. 일대다 관계.그렇다면 외래 키 배열을 만들고 싶었다면?음, 이것이 그것을 할 수 있는 한 가지 방법입니다!연결된 목록 테이블의 첫 번째 열을 가리키는 기본 테이블을 만든 다음 "정보" 필드 대신 원하는 정보 테이블에 대한 외래 키를 사용할 수 있습니다.

예:

양식을 유지하는 관료제가 있다고 가정해 보겠습니다.

다음과 같은 테이블이 있다고 가정해 보겠습니다. 파일 캐비닛

파일 캐비닛(

  • 캐비닛 ID(pk)
  • 파일 ID (FK))

각 열에는 캐비닛의 기본 키와 파일의 외래 키가 포함되어 있습니다.이러한 파일은 세금 양식, 건강 보험 서류, 견학 허가 전표 등이 될 수 있습니다.

파일(

  • 파일 ID(pk)

  • 파일 ID(fk)

  • 다음 파일 ID(fk)

)

이는 파일의 컨테이너 역할을 합니다.

파일(

  • 파일 ID(pk)

  • 파일에 대한 정보

)

이게 특정 파일이에요

특정 요구 사항에 따라 이 작업을 수행하는 더 좋은 방법이 있을 수 있습니다.이 예는 단지 가능한 사용법을 보여줍니다.

열에 오프셋(목록 인덱스 위치)이 포함되도록 하여 목록을 저장할 수 있습니다. 중간에 삽입하면 새 상위 항목 위로 모두 증가한 다음 삽입을 수행합니다.

SERIAL '인덱스'를 100씩 증가시키되 Prev+Next / 2와 같은 '인덱스'를 사용하여 중간 값을 수동으로 추가하십시오.100개 행이 포화되면 인덱스를 다시 100개로 다시 정렬하세요.

이는 기본 인덱스와의 순서를 유지해야 합니다.

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