Programming

SQL Server 데이터베이스에서 단일 행 구성 테이블 사용

procodes 2020. 6. 21. 20:46
반응형

SQL Server 데이터베이스에서 단일 행 구성 테이블 사용 나쁜 생각?


쇼핑 카트 응용 프로그램을 개발할 때 관리자의 기본 설정 및 요구 사항에 따라 설정 및 구성을 저장해야한다는 것을 알았습니다. 이 정보는 회사 정보, 배송 계정 ID, PayPal API 키, 알림 환경 설정 등 모든 것이 될 수 있습니다.

관계형 데이터베이스 시스템에 단일 행을 저장하기 위해 테이블을 작성하는 것은 매우 부적절한 것 같습니다.

이 정보를 저장하는 적절한 방법은 무엇입니까?

참고 : 내 DBMS는 SQL Server 2008이며 프로그래밍 계층은 ASP.NET (C #)으로 구현됩니다.


나는 과거에 단일 행 테이블과 키 / 값 쌍 테이블의 두 가지 방법을 수행했으며 각 접근 방식에는 양수와 음수가 있습니다.

단일 행

  • 양수 : 값이 올바른 유형으로 저장됩니다
  • 긍정적 : 코드로 다루기가 더 쉽습니다 (위로 인해)
  • 양수 : 기본값은 각 설정에 개별적으로 제공 될 수 있습니다
  • 부정 : 새 설정을 추가하려면 스키마를 변경해야합니다.
  • 음수 : 설정이 많으면 테이블이 매우 넓어 질 수 있습니다.

키 / 값 쌍

  • 긍정적 : 새로운 설정을 추가 할 때 스키마를 변경할 필요가 없습니다.
  • 양수 : 테이블 스키마가 좁고 새로운 설정에 추가 행이 사용됩니다.
  • 음수 : 각 설정의 기본값이 동일합니다 (널 / 빈?).
  • 음수 : 모든 것이 문자열로 저장되어야합니다 (예 : nvarchar)
  • 부정적 : 코드에서 설정을 처리 할 때 설정 유형을 알고 전송해야합니다.

단일 행 옵션은 작업하기 가장 쉬운 옵션입니다. 이는 각 설정을 데이터베이스에 올바른 유형으로 저장할 수 있고 설정 유형과 조회 키를 코드에 저장할 필요가 없기 때문입니다.

이 접근 방식을 사용하는 데 관심이있는 한 가지는 "특별한"단일 행 설정 테이블에 여러 행이있는 것이 었습니다. 나는 이것을 SQL Server에서 극복했다.

  • 기본값이 0 인 새 비트 열 추가
  • 이 열의 값이 0인지 확인하기위한 점검 제한 조건 작성
  • 비트 열에 고유 제한 조건 작성

이는 비트 열의 값이 0이므로 테이블에 하나의 행만 존재할 수 있지만 고유 제한 조건으로 인해 해당 값을 가진 행이 하나만있을 수 있음을 의미합니다.


정보 유형 및 정보 값에 대한 열이있는 테이블을 작성해야합니다 (적어도). 이렇게하면 새 정보가 추가 될 때마다 새 열을 만들지 않아도됩니다.


단일 행이 정상적으로 작동합니다. 그것은 강한 유형을 가질 것입니다 :

show_borders    bit
admin_name      varchar(50)
max_users       int

한 가지 단점은 alter table새 설정을 추가하기 위해 스키마 변경 ( )이 필요하다는 것입니다 . 하나의 대안은 다음과 같은 테이블로 끝나는 정규화입니다.

pref_name       varchar(50) primary key
pref_value      varchar(50) 

이것은 약한 유형 (모든 것이 varchar 임)을 갖지만 새로운 설정을 추가하는 것은 단지 행을 추가하는 것입니다. 데이터베이스 쓰기 액세스로 할 수있는 일입니다.


개인적으로, 그것이 효과적이라면 단일 행에 저장합니다. SQL 테이블에 저장하는 것이 과잉입니까? 아마, 그러나 그렇게 할 때 실질적인 피해는 없습니다.


정규화 된 접근 방식으로 새 구성 매개 변수를 추가 할 때 스키마를 변경할 필요는 없지만 새 값을 처리하기 위해 코드를 변경하는 중일 수 있습니다.

배포에 "대체 테이블"을 추가하는 것이 단일 행 접근 방식의 단순성 및 유형 안전성을위한 큰 절충안처럼 보이지는 않습니다.


가장 간단한 상황을 제외하고 모든 구성 매개 변수를 단일 행에 배치하면 많은 단점이 있습니다. 나쁜 생각입니다 ...

구성 및 / 또는 사용자 기본 설정 유형의 정보를 저장하는 편리한 방법은 XML 입니다. 많은 DBMS가 XML 데이터 형식을 지원합니다. XML 구문을 사용하면이 구성이 발전함에 따라 구성을 설명하는 "언어"및 구조를 사용할 수 있습니다. XML의 장점 중 하나는 계층 구조를 암시 적으로 지원한다는 것입니다. 예를 들어 번호가 붙은 접미사로 이름을 지정하지 않고도 작은 구성 매개 변수 목록을 저장할 수 있습니다. XML 형식의 가능한 단점은이 데이터를 검색하고 일반적으로 수정하는 것이 다른 접근 방식만큼 간단하지는 않지만 (복잡하지는 않지만 단순 / 자연적인 것은 아님)

관계형 모델에 더 가깝게 유지 하려면 Entity-Attribute-Value 모델 이 필요할 것입니다. 개별 값은 일반적으로 다음과 같은 테이블에 저장됩니다.

EntityId     (foreign key to the "owner" of this attribute)
AttributeId  (foreign key to the "metadata" table where the attribute is defined)
StringValue  (it is often convenient to have different columns of different types
IntValue      allowing to store the various attributes in a format that befits 
              them)

여기서 AttributeId는 가능한 각 속성 (귀하의 경우 "구성 매개 변수")이 정의 된 테이블에 대한 외래 키입니다.

AttributeId  (Primary Key)
Name
AttributeType     (some code  S = string, I = Int etc.)
Required          (some boolean indicating that this is required)
Some_other_fields   (for example to define in which order these attributes get displayed etc...)

마지막으로 EntityId를 사용하면 이러한 다양한 속성을 "소유"하는 일부 엔티티를 식별 할 수 있습니다. 귀하의 경우 UserId이거나 관리 할 구성이 하나 뿐인 경우에도 암시적일 수 있습니다.

Aside from allowing the list of possible configuration parameters to grow as the application evolves, the EAV model places the "meta data", i.e. the data pertaining to the Attribute themselves, in datatables, hence avoiding all the hard-coding of column names commonly seen when the configuration parameters are stored in a single row.


A Key and Value pair is similar to a .Net App.Config which can store configuration settings.

So when you want to retrieve the value you could do:

SELECT value FROM configurationTable
WHERE ApplicationGroup = 'myappgroup'
AND keyDescription = 'myKey';

A common way to do this is to have a "properties" table simmular to a properties file. Here you can store all your app constants, or not so constant things that you just need to have around.

You can then grab the info from this table as you need it. Likewise, as you find you have some other setting to save, you can add it in. Here is an example:

property_entry_table

[id, scope, refId, propertyName, propertyValue, propertyType] 
1, 0, 1, "COMPANY_INFO", "Acme Tools", "ADMIN"  
2, 0, 1, "SHIPPING_ID", "12333484", "ADMIN"  
3, 0, 1, "PAYPAL_KEY", "2143123412341", "ADMIN"   
4, 0, 1, "PAYPAL_KEY", "123412341234123", "ADMIN"  
5, 0, 1, "NOTIF_PREF", "ON", "ADMIN"  
6, 0, 2, "NOTIF_PREF", "OFF", "ADMIN"   

This way you can store the data you have, and the data that you will have next year and don't know about yet :) .

In this example, your scope and refId can be used for whatever you want on the back end. So if propertyType "ADMIN" has a scope 0 refId 2, you know what preference it is.

Property type comes in hand when, someday, you need to store non-admin info in here as well.

Note that you should not store cart data this way, or lookups for that matter. However if the data is System specific, then you can certainly use this method.

For example: If you want to store your DATABASE_VERSION, you'd use a table like this. That way, when you need to upgrade the app, you can check the properties table to see what version of your software the client has.

The point is you do not want to use this for things that pertain to the cart. Keep you business logic in well defined relational tables. The properties table is for system info only.


I'm not sure a single row is the best implementation for configuration. You might be better off having a row per configuration item with two columns (configName, configValue), although this will require casting all of your values to strings and back.

Regardless, there's no harm in using a single row for global config. The other options for storing it in the DB (global variables) are worse. You could control it by inserting your first configuration row, then disabling inserts on the table to prevent multiple rows.


You can do the Key/Value Pair without conversions by adding a column for each major type and one column telling you which column the data is in.

So your table would look something like:

id, column_num, property_name, intValue, floatValue, charValue, dateValue
1, 1, weeks, 51, , ,
2, 2, pi, , 3.14159, , 
3, 4, FiscYearEnd, , , , 1/31/2015
4, 3, CompanyName, , , ACME, 

It uses a little more room but at most you are using a few dozen attributes. You can use a case statement off the column_num value to pull / join the right field.


Sorry I come like, yeaars later. But anyways, what I do is simple and effective. I simply create a table with three () columns:

ID - int (11)

name - varchar (64)

value - text

What I do before creating a new config column, updating it or reading is to serialize the "value"! This way I am sure of the type (Well, php is :) )

For instance:

b:0; is for BOOLEAN (false)

b:1; is for BOOLEAN (true)

i:1988; is for INT

s:5:"Kader"; is for a STRING of 5 characters length

I hope this helps :)


Have a key column as varchar and a value column as JSON. 1 is numeric whereas "1" is a string. true and false are both boolean. You can have objects as well.

참고URL : https://stackoverflow.com/questions/2300356/using-a-single-row-configuration-table-in-sql-server-database-bad-idea

반응형