SQL Server에서 MariaDB로 변환
SSMS의 스크립트 생성으로 스키마와 데이터를 담아 만든 스크립트(.sql 또는 .sql.gz, UTF-16 또는 UTF-8)를 놓으면, 같은 테이블, 키, 인덱스, 데이터를 담은 MariaDB 스크립트를 다운로드할 수 있어요. MariaDB이(가) 그대로 담을 수 없는 값과 옮기지 않는 객체는 모두 보고서에 나와요.
18개 행 변환, 수정 3개, 거부 없음
shop_2024_sqlserver.sql의 테이블SQL Server 덤프 · SQL Server Management Objects(으)로 작성됨 · utf-8
orders10개 행1
11개 열 id int not null customer_id int not null status varchar(10) not null total decimal(19,4) not null items tinyint unsigned not null ordered_at datetime not null shipped_at datetime(6) note text details text order_ref uuid not null total_with_tax decimal(12,2) customers8개 행2
8개 열 id int not null name varchar(100) not null email varchar(200) not null country char(2) not null is_active tinyint(1) not null signed_up date created_at datetime not null row_version blob
변환되지 않음
- 뷰 paid_orders
- 트리거 orders_no_negative
데이터베이스마다 이 객체를 자체 언어로 작성해요. MariaDB에 맞게 다시 작성하세요.
-- Written by IntoSQL from a SQL Server dump. Load it with: mariadb --default-character-set=utf8mb4 <database> < <file>
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET SQL_MODE = 'NO_AUTO_VALUE_ON_ZERO,ALLOW_INVALID_DATES';
CREATE TABLE `orders` (
`id` int NOT NULL AUTO_INCREMENT,
`customer_id` int NOT NULL,
`status` varchar(10) NOT NULL DEFAULT 'pending',
`total` decimal(19,4) NOT NULL,
`items` tinyint unsigned NOT NULL DEFAULT 1,
`ordered_at` datetime NOT NULL,
`shipped_at` datetime(6),
`note` text,
`details` text,
`order_ref` uuid NOT NULL DEFAULT (uuid()),
`total_with_tax` decimal(12,2) GENERATED ALWAYS AS (cast(`total` * (1.16) AS DECIMAL(12,2))) STORED,
PRIMARY KEY (`id`),
KEY `idx_orders_customer` (`customer_id`),
KEY `idx_orders_status_date` (`status`,`ordered_at`),
CONSTRAINT `check2` CHECK (`status` = 'cancelled' OR `status` = 'shipped' OR `status` = 'paid' OR `status` = 'pending'),
CONSTRAINT `check3` CHECK (`total` >= (0)),
FOREIGN KEY (`customer_id`) REFERENCES `customers` (`id`)
) AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
CREATE TABLE `customers` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`email` varchar(200) NOT NULL,
`country` char(2) NOT NULL DEFAULT 'US',
`is_active` tinyint(1) NOT NULL DEFAULT 1,
`signed_up` date,
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`row_version` blob,
PRIMARY KEY (`id`),
UNIQUE KEY (`email`)
) AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='People who bought at least once';
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (1,'Ana Martínez','ana@example.com','MX',1,'2023-01-15','2023-01-15 10:24:00.000000');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (2,'Zoë Müller','zoe@example.de','DE',1,'2023-02-03','2023-02-03 08:11:42.000000');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (3,'José Peña','jose@example.es','ES',0,'2023-03-21','2023-03-21 19:05:17.000000');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (4,'李雷','lilei@example.cn','CN',1,'2023-05-09','2023-05-09 02:40:00.000000');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (5,'Noah O\'Brien','noah@example.ie','IE',1,NULL,'2023-06-30 14:00:00.000000');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (6,'Amélie Laurent','amelie@example.fr','FR',1,'2024-01-02','2024-01-02 09:30:00.000000');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (7,'Ravi Patel','ravi@example.in','IN',0,'2024-02-29','2024-02-29 23:59:59.000000');
INSERT INTO `customers` (`id`,`name`,`email`,`country`,`is_active`,`signed_up`,`created_at`) VALUES (8,'Sofia Rossi 🌻','sofia@example.it','IT',1,'2024-04-12','2024-04-12 12:12:12.000000');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (1,1,'shipped',129.9000,3,'2024-03-01T10:00:00.000000','2024-03-02T16:30:00.123456',NULL,'{"gift": false}','0b7a4c2e-3f1d-4e8a-9c55-1a2b3c4d5e6f');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (2,2,'paid',54.0000,1,'2024-03-02T11:15:00.000000',NULL,'Gift wrap 🎁','{"gift": true, "wrap": "red"}','1c8b5d3f-4a2e-4f9b-8d66-2b3c4d5e6f70');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (3,1,'cancelled',12.5000,1,'2024-03-03T09:45:00.000000',NULL,'Customer changed their mind',NULL,'2d9c6e4a-5b3f-4a0c-9e77-3c4d5e6f7081');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (4,4,'shipped',980.0000,12,'2024-03-05T02:10:00.000000','2024-03-07T08:00:00.000000','请小心轻放','{"fragile": true}','3e0d7f5b-6c4a-4b1d-8f88-4d5e6f708192');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (5,5,'pending',45.7500,2,'2024-03-08T17:20:00.000000',NULL,'Leave at the door; ring twice',NULL,'4f1e806c-7d5b-4c2e-9a99-5e6f708192a3');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (6,6,'shipped',310.4000,5,'2024-03-10T13:00:00.000000','2024-03-11T09:00:00.000000','Fragile: "glass"','{"fragile": true}','50f2917d-8e6c-4d3f-8baa-6f708192a3b4');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (7,8,'paid',76.2000,2,'2024-03-11T18:45:00.000000',NULL,NULL,NULL,'6103a28e-9f7d-4e40-9cbb-708192a3b4c5');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (8,2,'shipped',19.9900,1,'2024-03-12T08:00:00.000000','9999-12-31T23:59:59.999999','Shipped date set to the maximum by an old import',NULL,'7214b39f-a08e-4f51-8dcc-8192a3b4c5d6');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (9,3,'shipped',64.0000,2,'2024-03-14T15:30:00.000000','2024-03-15T10:00:00.000000','Two parcels','{"parcels": [1, 2]}','8325c4a0-b19f-4062-9edd-92a3b4c5d6e7');
INSERT INTO `orders` (`id`,`customer_id`,`status`,`total`,`items`,`ordered_at`,`shipped_at`,`note`,`details`,`order_ref`) VALUES (10,7,'paid',1499.0000,1,'2024-03-15T21:05:00.000000',NULL,'C:\\Users\\ravi\\invoice.pdf',NULL,'9436d5b1-c2a0-4173-8fee-a3b4c5d6e7f8');
SET UNIQUE_CHECKS = 1;
SET FOREIGN_KEY_CHECKS = 1;
수정 사항
- orders의 "shipped_at" 열은 datetime2(7)이고 MariaDB이(가) 유지하는 것보다 초 자릿수가 많아서, datetime(6)(으)로 바꾸고 마지막 자릿수를 잘라요.
- customers의 "created_at" 열에는 시간대가 있는 시점이 들어 있어요. MariaDB에는 시간대를 유지하는 타입이 없어서 datetime(으)로 UTC로 저장해요.
- customers의 "row_version" 열은 SQL Server가 자동으로 설정하는 행 버전이에요. 덤프에 그 값이 없어서 blob(으)로 바꾸고 비워 둬요.
확인 필요
- 원본에서 6개 텍스트 열은 대소문자를 구분하지 않고 비교해요. MariaDB은 정확히 비교하므로 고유 키와 검색 결과가 달라질 수 있어요. 필요한 열에 대소문자를 구분하지 않는 콜레이션이나 열 타입을 쓰세요.
- 뷰, 트리거, 루틴, 이벤트 2개가 변환되지 않았어요. 보고서에 각각 나와 있어요. MariaDB에서 직접 다시 만드세요.
- orders의 체크 제약 check1을(를) MariaDB용으로 쓸 수 없어(function isjson) 만들지 않았어요. 중요하다면 체크 제약을 직접 작성하세요.
- orders의 인덱스 idx_orders_pending은(는) MariaDB용으로 쓸 수 없는 식을 사용해서(neither MySQL 5.7 nor MariaDB index an expression) 만들지 않았어요. 쿼리에 필요하면 인덱스를 직접 만드세요.
파일은 이 컴퓨터에서 변환되고 업로드되지 않아요.
다른 샘플:
SQL Server에서 MariaDB로 바뀌는 점
각 행은 변환기가 적용하는 규칙이며, 규칙이 데이터를 바꿀 때 보고서에 쓰는 줄이 함께 나와요.
bit
tinyint(1)
MariaDB의 BOOLEAN은 TINYINT(1)이에요. bit처럼 1과 0이에요.
char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text
char(n), 1024자까지는 varchar(n), 그 이상은 text 타입
텍스트는 utf8mb4로 모든 문자를 유지해요. 키에 있는 열은 키가 담을 수 있는 최대 길이인 varchar(768)까지예요.
decimal(p,s), money, smallmoney
decimal(p,s), money는 decimal(19,4)
decimal은 SQL Server의 38자리보다 많은 65자리를 담으므로 모든 값이 정확해요.
datetime, datetime2, smalldatetime
datetime(p)
datetime은 양쪽 모두 시계에 표시된 시각이에요.
datetime2(7), time(7) and datetimeoffset(7)
초 단위 6자리, 7번째 자리는 잘림
MariaDB는 마이크로초까지 유지해요. 7번째 자리(100나노초)는 반올림하지 않고 잘라서, 어떤 값도 다음 초나 다음 날로 넘어가지 않아요.
보고서 줄: fraction_cut
datetimeoffset
UTC 기준 datetime(p)
MariaDB의 TIMESTAMP는 2038년까지만 담아서 시점을 UTC 기준 datetime으로 저장해요. 각 값의 오프셋과 상관없이 같은 시점이에요.
보고서 줄: moments_as_utc
time
time(p)
같은 시각이에요.
dates before the year 1000
NULL
MariaDB는 1000년부터 9999년까지만 저장하지만 SQL Server는 1년까지 거슬러 올라가요. 그런 값은 NULL이 되고 보고서에 개수가 나와요.
보고서 줄: date_out_of_range
json (SQL Server 2025)
json, JSON 체크가 있는 longtext
같은 JSON 값이고, MariaDB의 JSON 함수로 읽을 수 있어요.
uniqueidentifier
uuid
같은 식별자를 소문자로 써요.
binary, varbinary, image
binary(n), varbinary(n), blob 타입
바이트는 바이트 그대로 남아요.
geometry, geography
SQL Server 자체 바이트를 담은 blob
SSMS는 공간 값을 SQL Server의 직렬화 형식으로 쓰고, 이를 바이트 단위로 그대로 유지해요.
보고서 줄: spatial_as_native
rowversion, timestamp
blob, 빈 값
행 버전은 SQL Server가 자동으로 설정하고, SSMS는 그 값을 스크립트에 넣지 않아요.
보고서 줄: rowversion_empty
xml, sql_variant, hierarchyid, vector
longtext
MariaDB에는 같은 타입이 없어요. xml과 sql_variant는 각 값의 텍스트를, hierarchyid는 /1/2/ 같은 경로를 유지해요.
보고서 줄: type_replaced
collations that ignore case (_CI_)
정확한 비교(utf8mb4_bin)
테이블은 utf8mb4_bin을 써서 SQL Server가 구분하던 값을 고유 키도 구분해요. 대소문자를 무시하던 열은 그 동작을 잃어요. 악센트 규칙은 버전마다 달라서 모든 버전에서 SQL Server와 일치하는 _ci 콜레이션은 없어요.
보고서 줄: case_insensitive_collation
IDENTITY
AUTO_INCREMENT, 가장 큰 id 다음부터 이어짐
기본 키의 첫 열이 번호를 매기고, 카운터는 가장 큰 id 다음부터 이어져요.
IDENTITY columns that don't lead the primary key
일반 정수
MariaDB는 테이블마다 키의 첫 열 하나만 번호를 매겨요. 다른 열은 카운터 없이 값을 유지해요.
보고서 줄: counter_dropped
CREATE SEQUENCE
같은 옵션의 CREATE SEQUENCE
MariaDB 시퀀스도 같은 방식으로 동작해요. SSMS는 시퀀스가 어디까지 진행했는지 스크립트에 넣지 않으므로, 만들 때의 값부터 시작해요.
computed columns
생성 열, PERSISTED면 STORED, 아니면 VIRTUAL
MariaDB도 같은 두 방식으로 계산해요. SQL Server처럼 NULL을 빈 값으로 보도록 CONCAT을 써요.
computed columns with functions MariaDB lacks
일반 열
쓸 수 없는 수식은 일반 열로 남고 보고서에 한 줄 기록돼요. SSMS는 계산 열의 값을 스크립트에 넣지 않아요.
보고서 줄: generated_not_translated
defaults with functions MariaDB lacks, and NEXT VALUE FOR
기본값 없음
쓸 수 없는 기본값은 제외하고 보고해요.
보고서 줄: default_not_translated
CHECK constraints
변환됨
같은 체크 제약이고, 각 행을 불러올 때 검사해요.
CHECK constraints with functions MariaDB lacks
만들지 않음
쓸 수 없는 체크 제약은 제외하고 보고해요.
보고서 줄: check_skipped
CHECK constraints added WITH NOCHECK or disabled
만들지 않음
SQL Server가 이 체크 제약을 적용하지 않으므로 행이 이를 위반할 수 있어요.
보고서 줄: check_not_enforced
filtered and columnstore indexes
만들지 않음
IntoSQL은 열 전체에 대한 b-tree 인덱스를 써요. 다른 인덱스는 불러온 뒤 다시 만드세요.
보고서 줄: index_skipped
foreign keys
외래 키, FOREIGN_KEY_CHECKS=0으로 불러옴
행은 어떤 순서로든 불러오고, 이후 키가 새 행을 검사해요.
foreign keys to tables the dump doesn't create
만들지 않음
키는 없는 테이블을 가리킬 수 없어요.
보고서 줄: foreign_key_skipped
tables on a partition scheme
모든 파티션의 행을 담은 하나의 테이블
행은 같아요. 필요하면 MariaDB에서 테이블을 다시 파티션으로 나누세요.
보고서 줄: partitions_dropped
temporal tables (SYSTEM_VERSIONING)
WITH SYSTEM VERSIONING, 현재 행부터 시작. 기록 테이블은 일반 테이블로
MariaDB는 이제부터 기록을 자동으로 유지해요. SQL Server의 기간 열과 기록 테이블은 그대로 복사돼요.
schemas
하나의 데이터베이스, 테이블 이름 앞에 스키마 이름
MariaDB의 스키마는 데이터베이스이고, 한 데이터베이스에 불러오는 스크립트는 이를 만들 수 없어요. dbo의 테이블은 이름을 유지해요.
보고서 줄: schemas_merged
NOT NULL columns with values that become NULL
NOT NULL 제거
값을 NULL로 바꿔야 했던 열은 NOT NULL을 유지할 수 없어요. 유지하면 불러오기가 멈춰요.
보고서 줄: not_null_relaxed
views, functions, procedures, triggers, synonyms, types and partition functions
보고서에 나열
코드가 T-SQL로 작성되어 있어서 직접 다시 만들 수 있도록 나열해요.
보고서 줄: not_converted_objects
scripts without CREATE TABLE (data only)
값으로 판단한 타입
데이터만 있는 스크립트에는 행만 있어서 타입을 값으로 판단해요.
보고서 줄: no_schema
expressions in INSERT values
NULL
데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요.
보고서 줄: expression_value
types IntoSQL doesn't know
longtext
텍스트는 어떤 값이든 담아요. 불러온 뒤 타입을 바꾸세요.
보고서 줄: unknown_type
NUL characters in text
유지
값은 NUL 문자를 이스케이프해서 복사해요.
text that isn't valid in its encoding
잘못된 바이트를 대체 문자로
스크립트는 UTF-8이므로 모든 값이 올바른 텍스트여야 해요.
보고서 줄: invalid_utf8_replaced
text decoded twice (ñ)
그대로 복사
스크립트에 정확히 이 문자들이 있으므로 그대로 복사하고, 보고서에서 알려 줘요.
보고서 줄: mojibake_suspected
| SQL Server에서 | MariaDB에서 | 보고서 줄 |
|---|---|---|
| bit | tinyint(1)MariaDB의 BOOLEAN은 TINYINT(1)이에요. bit처럼 1과 0이에요. | |
| char(n), varchar(n), nchar(n), nvarchar(n), varchar(max), text | char(n), 1024자까지는 varchar(n), 그 이상은 text 타입텍스트는 utf8mb4로 모든 문자를 유지해요. 키에 있는 열은 키가 담을 수 있는 최대 길이인 varchar(768)까지예요. | |
| decimal(p,s), money, smallmoney | decimal(p,s), money는 decimal(19,4)decimal은 SQL Server의 38자리보다 많은 65자리를 담으므로 모든 값이 정확해요. | |
| datetime, datetime2, smalldatetime | datetime(p)datetime은 양쪽 모두 시계에 표시된 시각이에요. | |
| datetime2(7), time(7) and datetimeoffset(7) | 초 단위 6자리, 7번째 자리는 잘림MariaDB는 마이크로초까지 유지해요. 7번째 자리(100나노초)는 반올림하지 않고 잘라서, 어떤 값도 다음 초나 다음 날로 넘어가지 않아요. | fraction_cut |
| datetimeoffset | UTC 기준 datetime(p)MariaDB의 TIMESTAMP는 2038년까지만 담아서 시점을 UTC 기준 datetime으로 저장해요. 각 값의 오프셋과 상관없이 같은 시점이에요. | moments_as_utc |
| time | time(p)같은 시각이에요. | |
| dates before the year 1000 | NULLMariaDB는 1000년부터 9999년까지만 저장하지만 SQL Server는 1년까지 거슬러 올라가요. 그런 값은 NULL이 되고 보고서에 개수가 나와요. | date_out_of_range |
| json (SQL Server 2025) | json, JSON 체크가 있는 longtext같은 JSON 값이고, MariaDB의 JSON 함수로 읽을 수 있어요. | |
| uniqueidentifier | uuid같은 식별자를 소문자로 써요. | |
| binary, varbinary, image | binary(n), varbinary(n), blob 타입바이트는 바이트 그대로 남아요. | |
| geometry, geography | SQL Server 자체 바이트를 담은 blobSSMS는 공간 값을 SQL Server의 직렬화 형식으로 쓰고, 이를 바이트 단위로 그대로 유지해요. | spatial_as_native |
| rowversion, timestamp | blob, 빈 값행 버전은 SQL Server가 자동으로 설정하고, SSMS는 그 값을 스크립트에 넣지 않아요. | rowversion_empty |
| xml, sql_variant, hierarchyid, vector | longtextMariaDB에는 같은 타입이 없어요. xml과 sql_variant는 각 값의 텍스트를, hierarchyid는 /1/2/ 같은 경로를 유지해요. | type_replaced |
| collations that ignore case (_CI_) | 정확한 비교(utf8mb4_bin)테이블은 utf8mb4_bin을 써서 SQL Server가 구분하던 값을 고유 키도 구분해요. 대소문자를 무시하던 열은 그 동작을 잃어요. 악센트 규칙은 버전마다 달라서 모든 버전에서 SQL Server와 일치하는 _ci 콜레이션은 없어요. | case_insensitive_collation |
| IDENTITY | AUTO_INCREMENT, 가장 큰 id 다음부터 이어짐기본 키의 첫 열이 번호를 매기고, 카운터는 가장 큰 id 다음부터 이어져요. | |
| IDENTITY columns that don't lead the primary key | 일반 정수MariaDB는 테이블마다 키의 첫 열 하나만 번호를 매겨요. 다른 열은 카운터 없이 값을 유지해요. | counter_dropped |
| CREATE SEQUENCE | 같은 옵션의 CREATE SEQUENCEMariaDB 시퀀스도 같은 방식으로 동작해요. SSMS는 시퀀스가 어디까지 진행했는지 스크립트에 넣지 않으므로, 만들 때의 값부터 시작해요. | |
| computed columns | 생성 열, PERSISTED면 STORED, 아니면 VIRTUALMariaDB도 같은 두 방식으로 계산해요. SQL Server처럼 NULL을 빈 값으로 보도록 CONCAT을 써요. | |
| computed columns with functions MariaDB lacks | 일반 열쓸 수 없는 수식은 일반 열로 남고 보고서에 한 줄 기록돼요. SSMS는 계산 열의 값을 스크립트에 넣지 않아요. | generated_not_translated |
| defaults with functions MariaDB lacks, and NEXT VALUE FOR | 기본값 없음쓸 수 없는 기본값은 제외하고 보고해요. | default_not_translated |
| CHECK constraints | 변환됨같은 체크 제약이고, 각 행을 불러올 때 검사해요. | |
| CHECK constraints with functions MariaDB lacks | 만들지 않음쓸 수 없는 체크 제약은 제외하고 보고해요. | check_skipped |
| CHECK constraints added WITH NOCHECK or disabled | 만들지 않음SQL Server가 이 체크 제약을 적용하지 않으므로 행이 이를 위반할 수 있어요. | check_not_enforced |
| filtered and columnstore indexes | 만들지 않음IntoSQL은 열 전체에 대한 b-tree 인덱스를 써요. 다른 인덱스는 불러온 뒤 다시 만드세요. | index_skipped |
| foreign keys | 외래 키, FOREIGN_KEY_CHECKS=0으로 불러옴행은 어떤 순서로든 불러오고, 이후 키가 새 행을 검사해요. | |
| foreign keys to tables the dump doesn't create | 만들지 않음키는 없는 테이블을 가리킬 수 없어요. | foreign_key_skipped |
| tables on a partition scheme | 모든 파티션의 행을 담은 하나의 테이블행은 같아요. 필요하면 MariaDB에서 테이블을 다시 파티션으로 나누세요. | partitions_dropped |
| temporal tables (SYSTEM_VERSIONING) | WITH SYSTEM VERSIONING, 현재 행부터 시작. 기록 테이블은 일반 테이블로MariaDB는 이제부터 기록을 자동으로 유지해요. SQL Server의 기간 열과 기록 테이블은 그대로 복사돼요. | |
| schemas | 하나의 데이터베이스, 테이블 이름 앞에 스키마 이름MariaDB의 스키마는 데이터베이스이고, 한 데이터베이스에 불러오는 스크립트는 이를 만들 수 없어요. dbo의 테이블은 이름을 유지해요. | schemas_merged |
| NOT NULL columns with values that become NULL | NOT NULL 제거값을 NULL로 바꿔야 했던 열은 NOT NULL을 유지할 수 없어요. 유지하면 불러오기가 멈춰요. | not_null_relaxed |
| views, functions, procedures, triggers, synonyms, types and partition functions | 보고서에 나열코드가 T-SQL로 작성되어 있어서 직접 다시 만들 수 있도록 나열해요. | not_converted_objects |
| scripts without CREATE TABLE (data only) | 값으로 판단한 타입데이터만 있는 스크립트에는 행만 있어서 타입을 값으로 판단해요. | no_schema |
| expressions in INSERT values | NULL데이터베이스를 실행하지 않는 변환기는 이 식을 계산할 수 없어요. | expression_value |
| types IntoSQL doesn't know | longtext텍스트는 어떤 값이든 담아요. 불러온 뒤 타입을 바꾸세요. | unknown_type |
| NUL characters in text | 유지값은 NUL 문자를 이스케이프해서 복사해요. | |
| text that isn't valid in its encoding | 잘못된 바이트를 대체 문자로스크립트는 UTF-8이므로 모든 값이 올바른 텍스트여야 해요. | invalid_utf8_replaced |
| text decoded twice (ñ) | 그대로 복사스크립트에 정확히 이 문자들이 있으므로 그대로 복사하고, 보고서에서 알려 줘요. | mojibake_suspected |
스크립트를 MariaDB에 불러오기
스크립트는 테이블을 만들고 행을 복사한 다음 키, 인덱스, 외래 키를 추가해요. 그래서 빨리 불러오고 첫 오류에서 멈춰요.
mariadb --default-character-set=utf8mb4 mydb < sql_server.mariadb.sql외래 키는 덤프에 선언된 대로 만들고, mysqldump처럼 행을 불러오는 동안 FOREIGN_KEY_CHECKS=0을 써요.
큰 덤프는 서버와 같은 컴퓨터에서 클라이언트를 실행하고, 한 행이 아주 크면 max_allowed_packet을 늘리세요.
IntoSQL Pro는 데스크톱 앱이나 명령줄에서 파일을 MariaDB에 바로 불러와요. 스크립트를 따로 만들 필요가 없어요.
좋은 결과를 위한 SQL Server 덤프 방법
변환기는 덤프에 담긴 내용을 읽어요. 다음 옵션을 쓰면 더 많은 데이터가 덤프에 남아요:
- SSMS에서 데이터베이스를 마우스 오른쪽 버튼으로 클릭하고 태스크, 스크립트 생성을 차례로 고른 뒤 테이블을 선택하세요. dbatools, mssql-scripter 등 같은 라이브러리로 만든 도구도 같은 스크립트를 써요.
- 고급에서 스크립팅할 데이터 형식을 스키마 및 데이터로 설정하세요. 스키마만 담은 스크립트에는 테이블에 행이 없어요.
- SSMS 기본값인 유니코드나 UTF-8로 저장하세요. 둘 다 같은 방식으로 읽고, gzip도 쓸 수 있어요.
변환되지 않는 것
뷰, 함수, 프로시저, 트리거, 동의어, 규칙, 보안 정책은 T-SQL로 작성돼요. 보고서에 이름으로 나열되고 몰래 빠지는 일은 없으므로, MariaDB에 맞게 다시 작성할 수 있어요.
SQL Server에서 MariaDB로 변환에 관한 질문
여기에 답이 없나요? 문의 페이지로 연락하시면 담당자가 답장해요. 문의 페이지
덤프가 업로드되나요?
아니요. 변환기는 브라우저에서 실행되고 디스크의 덤프를 조각조각 읽으므로, 덤프가 컴퓨터 밖으로 나가지 않아요. 데스크톱 앱과 명령줄도 컴퓨터에서 변환해요.
덤프는 얼마나 커도 되나요?
변환기는 덤프 전체를 메모리에 올리지 않아요. 파일을 범위별로 두 번 읽고, 읽는 대로 스크립트를 써요. 수 GB 덤프도 브라우저, 데스크톱 앱, 명령줄에서 변환돼요.
SSMS가 저장하는 UTF-16 파일도 읽나요?
네. SSMS는 기본적으로 스크립트를 UTF-16으로 저장하고, 변환기는 UTF-16과 UTF-8을 gzip 여부와 상관없이, 배치 사이의 GO까지 똑같이 읽어요.
어떤 SQL Server 버전의 스크립트를 읽나요?
SQL Server 2017 이상에서 SSMS, dbatools, mssql-scripter로 만든 스크립트예요. 모든 테스트 스크립트는 SQL Server 2017, 2022, 2025에서 만들고 원본과 셀 단위로 비교해요.
IDENTITY 값은 유지되나요?
네, 테이블마다 한 열이요. 기본 키의 첫 열인 IDENTITY 열은 AUTO_INCREMENT가 되고 가장 큰 id 다음부터 이어져요. 시퀀스는 같은 옵션의 MariaDB 시퀀스가 돼요.
money, datetimeoffset 등 SQL Server 타입은 어떻게 되나요?
bit는 tinyint(1), money는 decimal(19,4), uniqueidentifier는 UUID, datetimeoffset은 UTC 기준 datetime이 돼요. 임시 테이블은 시스템 버전 관리를 유지해요. 대소문자를 무시하던 열은 정확히 비교하게 되고, 보고서에 어떤 열인지 나와요.
프로시저, 트리거, 뷰는 어떻게 되나요?
데이터베이스마다 자체 언어로 작성하므로 변환하지 않고 보고서에 이름으로 나열해요.
스크립트는 어떤 MariaDB 버전에서 불러올 수 있나요?
MariaDB 10.11 이상이에요. 모든 테스트 스크립트를 10.11과 11.4에서 불러오며, 문제가 생기면 첫 오류에서 멈춰요.