Przejdź do treści
Strona główna IntoSQL

Konwertuj MariaDB do PostgreSQL

Upuść zrzut z mariadb-dump, mysqldump, phpMyAdmin lub Adminer jako .sql lub .sql.gz i pobierz skrypt PostgreSQL z tymi samymi tabelami, kluczami, indeksami i danymi. Każda wartość, której PostgreSQL nie może przechować bez zmian, i każdy obiekt, którego nie przenosi, są wymienione w raporcie.

Twój plik
sqlshop_2024_mariadb.sqlPlik przykładowy, 6,6 kB
Twoja baza danych

18 wierszy przekonwertowanych, 8 poprawek, brak odrzuconych

Pokaż

Tabele w pliku shop_2024_mariadb.sqlZrzut MariaDB 11.8.9-MariaDB-ubu2404 · zapisany przez mariadb-dump · utf8mb4

  • customers8 wierszy3
    8 kolumn
    idbigint not null
    namevarchar(100) not null
    emailvarchar(150) not null
    countryvarchar(2) not null
    is_activeboolean not null
    signed_update
    created_attimestamptz(0) not null
    last_ipinet
  • orders10 wierszy5
    12 kolumn
    idbigint not null
    customer_idbigint not null
    statustext not null
    totalnumeric(10,2) not null
    itemsinteger not null
    ordered_attimestamp(0) not null
    shipped_attimestamp(0)
    notevarchar(255)
    order_refuuid not null
    invoiceinteger not null
    detailsjsonb
    updated_attimestamptz(0) not null
-- Written by IntoSQL from a MySQL dump. Load it with: psql -v ON_ERROR_STOP=1 -f <file>
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET synchronous_commit = off;
SET maintenance_work_mem = '512MB';

CREATE SEQUENCE invoice_numbers INCREMENT BY 1 MINVALUE 1 MAXVALUE 9223372036854775806 START WITH 1000;
SELECT setval('invoice_numbers', 2000, false);
CREATE TABLE customers (
    id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    name varchar(100) NOT NULL,
    email varchar(150) NOT NULL,
    country varchar(2) DEFAULT 'US' NOT NULL,
    is_active boolean DEFAULT true NOT NULL,
    signed_up date,
    created_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
    last_ip inet,
    CONSTRAINT customers_id_check CHECK (id >= 0)
);

CREATE TABLE orders (
    id bigint GENERATED BY DEFAULT AS IDENTITY NOT NULL,
    customer_id bigint NOT NULL,
    status text DEFAULT 'pending' NOT NULL,
    total numeric(10,2) NOT NULL,
    items integer DEFAULT 1 NOT NULL,
    ordered_at timestamp(0) NOT NULL,
    shipped_at timestamp(0),
    note varchar(255),
    order_ref uuid NOT NULL,
    invoice integer DEFAULT (nextval('invoice_numbers')) NOT NULL,
    details jsonb,
    updated_at timestamptz(0) DEFAULT CURRENT_TIMESTAMP NOT NULL,
    CONSTRAINT orders_id_check CHECK (id >= 0),
    CONSTRAINT orders_customer_id_check CHECK (customer_id >= 0),
    CONSTRAINT orders_status_check CHECK (status IN ('pending', 'paid', 'shipped', 'cancelled', '')),
    CONSTRAINT orders_items_check CHECK (items >= 0)
);

COPY customers (id, name, email, country, is_active, signed_up, created_at, last_ip) FROM stdin;
1	Ana Martínez	ana@example.com	MX	t	2023-01-15	2023-01-15 10:24:00+00:00	::ffff:203.0.113.7
2	Zoë Müller	zoe@example.de	DE	t	2023-02-03	2023-02-03 08:11:42+00:00	2001:db8::1
3	José Peña	jose@example.es	ES	f	2023-03-21	2023-03-21 19:05:17+00:00	\N
4	李雷	lilei@example.cn	CN	t	2023-05-09	2023-05-09 02:40:00+00:00	::ffff:198.51.100.23
5	Noah O'Brien	noah@example.ie	IE	t	\N	2023-06-30 14:00:00+00:00	\N
6	Amélie Laurent	amelie@example.fr	FR	t	2024-01-02	2024-01-02 09:30:00+00:00	2001:db8:85a3::8a2e:370:7334
7	Ravi Patel	ravi@example.in	IN	f	2024-02-29	2024-02-29 23:59:59+00:00	::ffff:192.0.2.200
8	Sofia Rossi 🌻	sofia@example.it	IT	t	2024-04-12	2024-04-12 12:12:12+00:00	\N
\.

COPY orders (id, customer_id, status, total, items, ordered_at, shipped_at, note, order_ref, invoice, details, updated_at) FROM stdin;
1	1	shipped	129.90	3	2024-03-01 10:00:00	2024-03-02 16:30:00	\N	0b7a4c2e-3f1d-4e8a-9c55-1a2b3c4d5e6f	1000	{"gift": false}	2024-03-02 16:30:00+00:00
2	2	paid	54.00	1	2024-03-02 11:15:00	\N	Gift wrap 🎁	1c8b5d3f-4a2e-4f9b-8d66-2b3c4d5e6f70	1001	{"gift": true, "wrap": "red"}	2024-03-02 11:20:00+00:00
3	1	cancelled	12.50	1	2024-03-03 09:45:00	\N	Customer changed their mind	2d9c6e4a-5b3f-4a0c-9e77-3c4d5e6f7081	1002	\N	2024-03-03 10:00:00+00:00
4	4	shipped	980.00	12	2024-03-05 02:10:00	2024-03-07 08:00:00	请小心轻放	3e0d7f5b-6c4a-4b1d-8f88-4d5e6f708192	1003	{"fragile": true}	2024-03-07 08:00:00+00:00
5	5	pending	45.75	2	2024-03-08 17:20:00	\N	Leave at the door; ring twice	4f1e806c-7d5b-4c2e-9a99-5e6f708192a3	1004	\N	2024-03-08 17:20:00+00:00
6	6	shipped	310.40	5	2024-03-10 13:00:00	2024-03-11 09:00:00	Fragile: "glass"	50f2917d-8e6c-4d3f-8baa-6f708192a3b4	1005	{"fragile": true}	2024-03-11 09:00:00+00:00
7	8	paid	76.20	2	2024-03-11 18:45:00	\N	\N	6103a28e-9f7d-4e40-9cbb-708192a3b4c5	1006	\N	2024-03-11 18:46:00+00:00
8	2		19.99	1	2024-03-12 08:00:00	\N	Status lost in an old import	7214b39f-a08e-4f51-8dcc-8192a3b4c5d6	1007	\N	2024-03-12 08:00:00+00:00
9	3	shipped	64.00	2	2024-03-14 15:30:00	\N	Shipping date never recorded	8325c4a0-b19f-4062-9edd-92a3b4c5d6e7	1008	{"parcels": [1, 2]}	2024-03-15 10:00:00+00:00
10	7	paid	1499.00	1	2024-03-15 21:05:00	\N	C:\\Users\\ravi\\invoice.pdf	9436d5b1-c2a0-4173-8fee-a3b4c5d6e7f8	1009	\N	2024-03-15 21:05:00+00:00
\.


-- Keys, indexes and constraints, after the rows so each builds once.
CREATE UNIQUE INDEX customers_pkey ON customers (id);
CREATE UNIQUE INDEX customers_uq_email ON customers (email);
CREATE UNIQUE INDEX orders_pkey ON orders (id);
CREATE INDEX orders_idx_customer ON orders (customer_id);
CREATE INDEX orders_idx_status_date ON orders (status, ordered_at);
ALTER TABLE customers ADD CONSTRAINT customers_pkey PRIMARY KEY USING INDEX customers_pkey;
ALTER TABLE customers ADD CONSTRAINT customers_uq_email UNIQUE USING INDEX customers_uq_email;
ALTER TABLE orders ADD CONSTRAINT orders_pkey PRIMARY KEY USING INDEX orders_pkey;
ALTER TABLE orders ADD CONSTRAINT fk_orders_customer FOREIGN KEY (customer_id) REFERENCES customers (id) NOT VALID;
DO $f$ BEGIN
    ALTER TABLE orders VALIDATE CONSTRAINT fk_orders_customer;
EXCEPTION WHEN foreign_key_violation THEN
    RAISE WARNING 'foreign key % has rows without a parent: it stays NOT VALID, and new rows are checked', 'fk_orders_customer';
END $f$;
SELECT setval(pg_get_serial_sequence('customers', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM customers)::numeric, 0) + 1, 1001), 9223372036854775807)::bigint, false);
COMMENT ON TABLE customers IS 'People who bought at least once';
SELECT setval(pg_get_serial_sequence('orders', 'id'), LEAST(GREATEST(COALESCE((SELECT max(id) FROM orders)::numeric, 0) + 1, 5001), 9223372036854775807)::bigint, false);
CREATE FUNCTION orders_updated_at_on_update() RETURNS trigger LANGUAGE plpgsql AS $f$
BEGIN
    IF NEW IS DISTINCT FROM OLD AND NEW.updated_at IS NOT DISTINCT FROM OLD.updated_at THEN
        NEW.updated_at := CURRENT_TIMESTAMP;
    END IF;
    RETURN NEW;
END
$f$;
CREATE TRIGGER orders_updated_at_on_update BEFORE UPDATE ON orders FOR EACH ROW EXECUTE FUNCTION orders_updated_at_on_update();

Poprawki

  1. "id" w tabeli customers jest bez znaku, więc ma typ bigint z ograniczeniem CHECK, że nie jest ujemna.
  2. "signed_up" w tabeli customers dopuszcza teraz NULL: części jej wartości nie dało się zapisać i są NULL.
  3. Wartość domyślna "signed_up" w tabeli customers, 0000‑00‑00, nie jest datą akceptowaną przez PostgreSQL, więc kolumna nie ma wartości domyślnej.
  4. "customer_id" w tabeli orders jest bez znaku, więc ma typ bigint z ograniczeniem CHECK, że nie jest ujemna.
  5. "id" w tabeli orders jest bez znaku, więc ma typ bigint z ograniczeniem CHECK, że nie jest ujemna.
  6. "items" w tabeli orders jest bez znaku, więc ma typ integer z ograniczeniem CHECK, że nie jest ujemna.
  7. W "status" tabeli orders 1 wiersz zawiera pustą wartość, którą MySQL zapisuje dla błędnych danych; ograniczenie CHECK kolumny ją dopuszcza.
  8. "updated_at" w tabeli orders zmienia się na bieżący czas przy każdej aktualizacji; w PostgreSQL robi to wyzwalacz.

Do sprawdzenia

  • W "signed_up" tabeli customers zamieniono na NULL 1 wartość z zerową lub niemożliwą datą, np. 0000‑00‑00, bo PostgreSQL nie zapisuje takich dat. Jeśli te daty coś znaczą, zastąp je w źródle prawdziwymi, zanim zrobisz zrzut.
  • W "shipped_at" tabeli orders zamieniono na NULL 1 wartość z zerową lub niemożliwą datą, np. 0000‑00‑00 00:00:00, bo PostgreSQL nie zapisuje takich dat. Jeśli te daty coś znaczą, zastąp je w źródle prawdziwymi, zanim zrobisz zrzut.

Plik jest konwertowany na tym komputerze i nigdy nie jest wysyłany.

Inne przykłady:

Co zmienia się między MariaDB a PostgreSQL

Każdy wiersz to reguła stosowana przez konwerter, z wpisem, który dodaje do raportu, gdy reguła coś zmienia w twoich danych.

  • TINYINT(1), BOOL

    boolean, gdy każda wartość to 0 lub 1, w przeciwnym razie smallint

    BOOL w MySQL to TINYINT(1), który mieści dowolną liczbę od -128 do 127. Kolumna z samymi 0 i 1 staje się boolean; kolumna z 2 lub -1 pozostaje liczbą, aby żadna wartość nie zmieniła znaczenia.

    Wpis w raporcie: bool_kept_numeric

  • UNSIGNED integers

    następny szerszy typ całkowity z CHECK, że wartość nie jest ujemna; BIGINT UNSIGNED to bigint, gdy każda wartość się mieści, w przeciwnym razie numeric(20,0)

    PostgreSQL nie ma liczb całkowitych bez znaku. Szerszy typ mieści cały zakres bez znaku, a ograniczenie CHECK blokuje wartości ujemne, tak jak MySQL.

    Wpis w raporcie: unsigned_widened

  • ZEROFILL and display widths

    usunięte

    Dopełnienie zerami to sposób wyświetlania liczby, a nie jej część. Liczby zostają zachowane; jeśli dopełnienie jest ważne, formatuj je przy odczycie.

    Wpis w raporcie: zerofill_dropped

  • FLOAT(M,D)

    real lub double precision, bez skali

    Liczby zmiennoprzecinkowe w PostgreSQL nie mają stałej skali. Zapisane wartości są kopiowane bez zmian.

    Wpis w raporcie: float_scale_dropped

  • BIT(1), BIT(n)

    boolean, bit(n)

    Pojedynczy bit to tak lub nie; szersze pola bitowe zachowują każdy bit.

  • zero, partial or impossible dates (0000-00-00, 2024-02-30)

    NULL

    PostgreSQL przechowuje tylko prawdziwe daty kalendarzowe. MySQL zachowuje daty zerowe i niemożliwe, gdy pozwala na to tryb SQL; stają się NULL, a raport je liczy.

    Wpis w raporcie: invalid_date_null

  • NOT NULL columns with values that become NULL

    NOT NULL usunięte

    Kolumna, której wartości musiały stać się NULL, nie może zachować NOT NULL, bo ładowanie by się zatrzymało.

    Wpis w raporcie: not_null_relaxed

  • DEFAULT '0000-00-00'

    brak wartości domyślnej

    Wartość domyślna, której PostgreSQL nie może zapisać, jest pomijana, a nie zastępowana zmyśloną datą.

    Wpis w raporcie: zero_date_default

  • TIME

    time, gdy każda wartość mieści się w dobie, w przeciwnym razie interval

    TIME w MySQL to czas trwania od -838:59:59 do 838:59:59. Kolumna, której wartości mieszczą się w dobie, pozostaje godziną dnia; kolumna z dłuższymi lub ujemnymi wartościami staje się interval.

    Wpis w raporcie: time_as_interval

  • YEAR

    smallint z CHECK zakresu

    PostgreSQL nie ma typu roku; ograniczenie CHECK zachowuje te same wartości, na które pozwala MySQL.

  • CHAR(n)

    varchar(n)

    MySQL usuwa końcowe spacje z wartości CHAR przy odczycie, a char(n) w PostgreSQL dodałby je z powrotem, więc varchar(n) zachowuje wartości tak, jak zwraca je MySQL.

  • DATETIME

    timestamp

    DATETIME to wskazanie zegara bez strefy czasowej, jak timestamp w PostgreSQL.

  • TIMESTAMP

    timestamptz w strefie czasowej podanej w zrzucie, UTC, gdy jej nie podaje

    TIMESTAMP to moment w czasie. Zrzuty podają strefę, w której go zapisały (mysqldump zapisuje UTC); bez niej wartości są odczytywane jako UTC, a raport o tym mówi.

    Wpis w raporcie: timestamp_zone_assumed

  • ENUM

    text z CHECK dozwolonych wartości

    Tekst z ograniczeniem CHECK zachowuje te same wartości i łatwiej go zmienić niż typ enum w PostgreSQL.

  • ENUM holding '' (MySQL's error value)

    pusta wartość dopuszczona przez CHECK

    MySQL zapisuje pusty ciąg, gdy w łagodnym trybie SQL do ENUM trafia błędna wartość. Te wiersze są zachowywane, a ograniczenie CHECK je dopuszcza.

    Wpis w raporcie: enum_invalid_value

  • ENUM or SET holding values outside its list

    bez CHECK

    Wartości spoza listy nie przeszłyby ograniczenia CHECK, więc nie jest ono tworzone.

    Wpis w raporcie: enum_check_skipped

  • SET

    text[] z CHECK, że każdy element jest na liście

    Tablica przechowuje każdy element osobno, więc zapytania mogą sprawdzać przynależność.

  • JSON

    jsonb; json, gdy wartość zawiera \u0000

    jsonb to typ, który PostgreSQL dobrze indeksuje i przeszukuje, ale odrzuca sekwencję \u0000, więc kolumna z nią pozostaje json.

    Wpis w raporcie: json_not_jsonb

  • NUL bytes in text

    usunięte

    Tekst w PostgreSQL nie może zawierać bajtu NUL. Bajt jest usuwany, a raport liczy takie wartości.

    Wpis w raporcie: nul_removed

  • text that isn't valid in its character set

    błędne bajty jako znak zastępczy

    Tekst w PostgreSQL musi być poprawnym UTF-8.

    Wpis w raporcie: invalid_utf8_replaced

  • text decoded twice (ñ)

    skopiowane bez zmian

    Zrzut zawiera dokładnie te znaki, więc są kopiowane; raport je wskazuje.

    Wpis w raporcie: mojibake_suspected

  • AUTO_INCREMENT

    GENERATED BY DEFAULT AS IDENTITY, z licznikiem ustawionym za skopiowanymi id

    Kolumny identity przyjmują skopiowane id, a licznik idzie dalej od najwyższego z nich lub od AUTO_INCREMENT ze zrzutu, zależnie od tego, która wartość jest wyższa.

  • MyISAM AUTO_INCREMENT on the second column of a key

    jeden licznik dla tabeli

    MyISAM liczy osobno w każdej grupie pierwszej kolumny klucza; PostgreSQL ma jeden licznik na kolumnę.

    Wpis w raporcie: myisam_group_autoincrement

  • ON UPDATE CURRENT_TIMESTAMP

    wyzwalacz BEFORE UPDATE

    Wyzwalacz ustawia kolumnę na bieżący czas, gdy wiersz się zmienia, a aktualizacja jej nie ustawiła, tak jak MySQL.

    Wpis w raporcie: on_update_trigger

  • generated columns

    STORED

    PostgreSQL od 13 do 17 tylko przechowuje kolumny generowane; formuła jest ta sama.

    Wpis w raporcie: virtual_as_stored

  • generated columns with functions PostgreSQL lacks

    zwykła kolumna

    Formuła, której nie da się zapisać dla PostgreSQL, zostawia zwykłą kolumnę i wpis w raporcie.

    Wpis w raporcie: generated_not_translated

  • INVISIBLE columns

    zwykłe kolumny

    PostgreSQL nie ma niewidocznych kolumn.

    Wpis w raporcie: invisible_column

  • CHECK constraints

    przetłumaczone, wewnątrz CREATE TABLE

    Ograniczenia CHECK wewnątrz definicji są sprawdzane przy ładowaniu każdego wiersza, a nie osobnym skanem dla każdego z nich na końcu.

  • CHECK constraints with functions PostgreSQL lacks

    nie jest tworzone

    Ograniczenie CHECK, którego nie da się zapisać dla PostgreSQL, jest pomijane i zgłaszane w raporcie.

    Wpis w raporcie: check_skipped

  • CHECK ... NOT ENFORCED

    nie jest tworzone

    MySQL przechowuje te ograniczenia bez ich stosowania, więc wiersze mogą je łamać.

    Wpis w raporcie: check_not_enforced

  • defaults with functions PostgreSQL lacks

    brak wartości domyślnej

    Wartość domyślna, której nie da się zapisać dla PostgreSQL, jest pomijana i zgłaszana w raporcie.

    Wpis w raporcie: default_not_translated

  • keys and indexes on a prefix, c(20)

    indeks na left(c, 20)

    PostgreSQL indeksuje wyrażenia, więc indeksowany jest ten sam prefiks.

    Wpis w raporcie: prefix_unique

  • FULLTEXT indexes

    GIN na to_tsvector('simple', ...)

    Wyszukiwanie pełnotekstowe działa z @@ zamiast MATCH ... AGAINST.

    Wpis w raporcie: fulltext_as_gin

  • indexes on values over 2,000 bytes

    hash

    Wpis btree nie pomieści tak długich wartości; indeks hash nadal znajduje równe wartości.

    Wpis w raporcie: index_on_wide_values

  • SPATIAL indexes

    nie jest tworzony bez PostGIS

    Indeksy przestrzenne wymagają PostGIS.

    Wpis w raporcie: spatial_index_skipped

  • functional indexes PostgreSQL can't write

    nie jest tworzony

    Indeks na wyrażeniu, którego nie da się zapisać dla PostgreSQL, jest pomijany i zgłaszany w raporcie.

    Wpis w raporcie: index_skipped

  • foreign keys

    po danych, jako NOT VALID, potem sprawdzany z ostrzeżeniem o osieroconych wierszach

    Zrzuty ładują się z FOREIGN_KEY_CHECKS=0, a MyISAM nigdy nie sprawdza kluczy, więc wiersze bez rodzica są częste. Klucz jest tworzony najpierw i sprawdzany na końcu; osierocone wiersze zostawiają go jako NOT VALID z ostrzeżeniem, zamiast zatrzymać ładowanie.

  • foreign keys to columns without a unique key

    nie jest tworzony

    PostgreSQL wymaga klucza unikalnego na kolumnach, do których się odwołuje; InnoDB nie.

    Wpis w raporcie: foreign_key_skipped

  • table and column names

    małe litery, gdy nazwy pozostają unikalne

    Nazwy z małych liter można w PostgreSQL pisać bez cudzysłowów.

    Wpis w raporcie: identifier_renamed

  • names over 63 bytes

    skrócone z hashem

    Nazwy w PostgreSQL mają do 63 bajtów; hash odróżnia skrócone nazwy od siebie.

    Wpis w raporcie: name_shortened

  • GEOMETRY, POINT, POLYGON...

    WKB w bytea

    Bez PostGIS standardowy format well-known binary zachowuje dokładnie każdą geometrię.

    Wpis w raporcie: geometry_as_wkb

  • INET4, INET6, UUID (MariaDB)

    inet, uuid

    PostgreSQL ma te same typy.

  • BINARY, VARBINARY, BLOB

    bytea

    Bajty pozostają bajtami.

  • PARTITION BY

    jedna tabela

    Wiersze są te same; jeśli trzeba, podziel tabelę na partycje ponownie w PostgreSQL.

    Wpis w raporcie: partitions_dropped

  • WITH SYSTEM VERSIONING (MariaDB)

    tabela z bieżącymi wierszami

    Zrzut zawiera tylko bieżące wiersze.

    Wpis w raporcie: system_versioning_dropped

  • MyISAM, MEMORY and other engines

    zwykła tabela

    PostgreSQL ma jeden silnik tabel.

    Wpis w raporcie: engine_dropped

  • views, triggers, procedures, functions and events

    wymienione w raporcie

    Ich kod jest napisany w języku MySQL, więc trafiają na listę do ręcznego odtworzenia.

    Wpis w raporcie: not_converted_objects

  • dumps without CREATE TABLE

    typy odczytane z wartości

    Zrzut zrobiony z --no-create-info zawiera tylko wiersze, więc typy pochodzą z wartości.

    Wpis w raporcie: no_schema

  • geometries in a dump without CREATE TABLE

    WKB w bytea

    Format geometrii MySQL jest rozpoznawany po wartościach i zapisywany jako standardowe WKB.

    Wpis w raporcie: geometry_inferred

  • _ci collations

    dokładne porównanie

    PostgreSQL porównuje tekst dokładnie, chyba że ustawisz inaczej.

    Wpis w raporcie: case_insensitive_collation

  • SET NAMES utf8 from utf8mb4 tables

    przekonwertowane, z ostrzeżeniem

    mysqldump z MySQL 5.x domyślnie zapisuje 3-bajtowe utf8 i zastępuje każde emoji znakiem zapytania, zanim jakikolwiek konwerter zobaczy plik.

    Wpis w raporcie: dump_lost_four_byte_chars

  • dumps without SET NAMES whose text isn't UTF-8

    odczytane jako Latin-1 (Windows-1252)

    latin1 w MySQL to Windows-1252, zwykłe kodowanie takich zrzutów.

    Wpis w raporcie: charset_guessed

  • sjis, cp932, gbk, big5 dumps

    odczytane jako UTF-8, z ostrzeżeniem

    Te kodowania nie są jeszcze dekodowane.

    Wpis w raporcie: unsupported_charset

  • UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rows

    obliczone

    Niektóre narzędzia do zrzutów zapisują wartości jako takie wywołania; są odczytywane jako wartości, które zwracają, przy czym w geograficznym WKT najpierw jest długość geograficzna.

  • other expressions in rows

    NULL

    Konwerter, który nie uruchamia bazy danych, nie może ich obliczyć.

    Wpis w raporcie: expression_value

  • DEFAULT in VALUES

    wartość domyślna kolumny

    Dosłowna wartość domyślna jest kopiowana do wiersza.

    Wpis w raporcie: default_keyword_filled

  • DEFAULT in VALUES without a literal default

    NULL

    Nie ma wartości do skopiowania.

    Wpis w raporcie: default_keyword_null

  • REPLACE and INSERT IGNORE

    zwykłe wiersze

    Zrzut ma jeden wiersz na klucz, więc wiersze są te same.

    Wpis w raporcie: replace_as_insert

  • types IntoSQL doesn't know

    text

    Tekst mieści każdą wartość; zmień typ po załadowaniu.

    Wpis w raporcie: unknown_type

  • values that don't fit their column

    NULL

    Uszkodzony lub ręcznie pisany zrzut może zawierać wartości, których kolumna nie przyjmie; stają się NULL, aby reszta się załadowała.

    Wpis w raporcie: invalid_value_null

  • unreadable geometries

    NULL

    Bajtów, które nie są geometrią, nie da się zapisać jako geometrii.

    Wpis w raporcie: bad_geometry

  • CREATE SEQUENCE (MariaDB)

    CREATE SEQUENCE z bieżącą wartością

    Sekwencje w PostgreSQL przyjmują te same opcje.

  • VECTOR(n) (MariaDB 11.7+)

    jsonb z liczbami float jako tablicą

    PostgreSQL bez pgvector nie ma typu wektorowego; tablica JSON zachowuje każdą liczbę float, a rzutowanie jej po załadowaniu na typ vector z pgvector odczytuje ten sam tekst.

    Wpis w raporcie: type_replaced

W MariaDBW PostgreSQLWpis w raporcie
TINYINT(1), BOOLboolean, gdy każda wartość to 0 lub 1, w przeciwnym razie smallintBOOL w MySQL to TINYINT(1), który mieści dowolną liczbę od -128 do 127. Kolumna z samymi 0 i 1 staje się boolean; kolumna z 2 lub -1 pozostaje liczbą, aby żadna wartość nie zmieniła znaczenia.bool_kept_numeric
UNSIGNED integersnastępny szerszy typ całkowity z CHECK, że wartość nie jest ujemna; BIGINT UNSIGNED to bigint, gdy każda wartość się mieści, w przeciwnym razie numeric(20,0)PostgreSQL nie ma liczb całkowitych bez znaku. Szerszy typ mieści cały zakres bez znaku, a ograniczenie CHECK blokuje wartości ujemne, tak jak MySQL.unsigned_widened
ZEROFILL and display widthsusunięteDopełnienie zerami to sposób wyświetlania liczby, a nie jej część. Liczby zostają zachowane; jeśli dopełnienie jest ważne, formatuj je przy odczycie.zerofill_dropped
FLOAT(M,D)real lub double precision, bez skaliLiczby zmiennoprzecinkowe w PostgreSQL nie mają stałej skali. Zapisane wartości są kopiowane bez zmian.float_scale_dropped
BIT(1), BIT(n)boolean, bit(n)Pojedynczy bit to tak lub nie; szersze pola bitowe zachowują każdy bit.
zero, partial or impossible dates (0000-00-00, 2024-02-30)NULLPostgreSQL przechowuje tylko prawdziwe daty kalendarzowe. MySQL zachowuje daty zerowe i niemożliwe, gdy pozwala na to tryb SQL; stają się NULL, a raport je liczy.invalid_date_null
NOT NULL columns with values that become NULLNOT NULL usunięteKolumna, której wartości musiały stać się NULL, nie może zachować NOT NULL, bo ładowanie by się zatrzymało.not_null_relaxed
DEFAULT '0000-00-00'brak wartości domyślnejWartość domyślna, której PostgreSQL nie może zapisać, jest pomijana, a nie zastępowana zmyśloną datą.zero_date_default
TIMEtime, gdy każda wartość mieści się w dobie, w przeciwnym razie intervalTIME w MySQL to czas trwania od -838:59:59 do 838:59:59. Kolumna, której wartości mieszczą się w dobie, pozostaje godziną dnia; kolumna z dłuższymi lub ujemnymi wartościami staje się interval.time_as_interval
YEARsmallint z CHECK zakresuPostgreSQL nie ma typu roku; ograniczenie CHECK zachowuje te same wartości, na które pozwala MySQL.
CHAR(n)varchar(n)MySQL usuwa końcowe spacje z wartości CHAR przy odczycie, a char(n) w PostgreSQL dodałby je z powrotem, więc varchar(n) zachowuje wartości tak, jak zwraca je MySQL.
DATETIMEtimestampDATETIME to wskazanie zegara bez strefy czasowej, jak timestamp w PostgreSQL.
TIMESTAMPtimestamptz w strefie czasowej podanej w zrzucie, UTC, gdy jej nie podajeTIMESTAMP to moment w czasie. Zrzuty podają strefę, w której go zapisały (mysqldump zapisuje UTC); bez niej wartości są odczytywane jako UTC, a raport o tym mówi.timestamp_zone_assumed
ENUMtext z CHECK dozwolonych wartościTekst z ograniczeniem CHECK zachowuje te same wartości i łatwiej go zmienić niż typ enum w PostgreSQL.
ENUM holding '' (MySQL's error value)pusta wartość dopuszczona przez CHECKMySQL zapisuje pusty ciąg, gdy w łagodnym trybie SQL do ENUM trafia błędna wartość. Te wiersze są zachowywane, a ograniczenie CHECK je dopuszcza.enum_invalid_value
ENUM or SET holding values outside its listbez CHECKWartości spoza listy nie przeszłyby ograniczenia CHECK, więc nie jest ono tworzone.enum_check_skipped
SETtext[] z CHECK, że każdy element jest na liścieTablica przechowuje każdy element osobno, więc zapytania mogą sprawdzać przynależność.
JSONjsonb; json, gdy wartość zawiera \u0000jsonb to typ, który PostgreSQL dobrze indeksuje i przeszukuje, ale odrzuca sekwencję \u0000, więc kolumna z nią pozostaje json.json_not_jsonb
NUL bytes in textusunięteTekst w PostgreSQL nie może zawierać bajtu NUL. Bajt jest usuwany, a raport liczy takie wartości.nul_removed
text that isn't valid in its character setbłędne bajty jako znak zastępczyTekst w PostgreSQL musi być poprawnym UTF-8.invalid_utf8_replaced
text decoded twice (ñ)skopiowane bez zmianZrzut zawiera dokładnie te znaki, więc są kopiowane; raport je wskazuje.mojibake_suspected
AUTO_INCREMENTGENERATED BY DEFAULT AS IDENTITY, z licznikiem ustawionym za skopiowanymi idKolumny identity przyjmują skopiowane id, a licznik idzie dalej od najwyższego z nich lub od AUTO_INCREMENT ze zrzutu, zależnie od tego, która wartość jest wyższa.
MyISAM AUTO_INCREMENT on the second column of a keyjeden licznik dla tabeliMyISAM liczy osobno w każdej grupie pierwszej kolumny klucza; PostgreSQL ma jeden licznik na kolumnę.myisam_group_autoincrement
ON UPDATE CURRENT_TIMESTAMPwyzwalacz BEFORE UPDATEWyzwalacz ustawia kolumnę na bieżący czas, gdy wiersz się zmienia, a aktualizacja jej nie ustawiła, tak jak MySQL.on_update_trigger
generated columnsSTOREDPostgreSQL od 13 do 17 tylko przechowuje kolumny generowane; formuła jest ta sama.virtual_as_stored
generated columns with functions PostgreSQL lackszwykła kolumnaFormuła, której nie da się zapisać dla PostgreSQL, zostawia zwykłą kolumnę i wpis w raporcie.generated_not_translated
INVISIBLE columnszwykłe kolumnyPostgreSQL nie ma niewidocznych kolumn.invisible_column
CHECK constraintsprzetłumaczone, wewnątrz CREATE TABLEOgraniczenia CHECK wewnątrz definicji są sprawdzane przy ładowaniu każdego wiersza, a nie osobnym skanem dla każdego z nich na końcu.
CHECK constraints with functions PostgreSQL lacksnie jest tworzoneOgraniczenie CHECK, którego nie da się zapisać dla PostgreSQL, jest pomijane i zgłaszane w raporcie.check_skipped
CHECK ... NOT ENFORCEDnie jest tworzoneMySQL przechowuje te ograniczenia bez ich stosowania, więc wiersze mogą je łamać.check_not_enforced
defaults with functions PostgreSQL lacksbrak wartości domyślnejWartość domyślna, której nie da się zapisać dla PostgreSQL, jest pomijana i zgłaszana w raporcie.default_not_translated
keys and indexes on a prefix, c(20)indeks na left(c, 20)PostgreSQL indeksuje wyrażenia, więc indeksowany jest ten sam prefiks.prefix_unique
FULLTEXT indexesGIN na to_tsvector('simple', ...)Wyszukiwanie pełnotekstowe działa z @@ zamiast MATCH ... AGAINST.fulltext_as_gin
indexes on values over 2,000 byteshashWpis btree nie pomieści tak długich wartości; indeks hash nadal znajduje równe wartości.index_on_wide_values
SPATIAL indexesnie jest tworzony bez PostGISIndeksy przestrzenne wymagają PostGIS.spatial_index_skipped
functional indexes PostgreSQL can't writenie jest tworzonyIndeks na wyrażeniu, którego nie da się zapisać dla PostgreSQL, jest pomijany i zgłaszany w raporcie.index_skipped
foreign keyspo danych, jako NOT VALID, potem sprawdzany z ostrzeżeniem o osieroconych wierszachZrzuty ładują się z FOREIGN_KEY_CHECKS=0, a MyISAM nigdy nie sprawdza kluczy, więc wiersze bez rodzica są częste. Klucz jest tworzony najpierw i sprawdzany na końcu; osierocone wiersze zostawiają go jako NOT VALID z ostrzeżeniem, zamiast zatrzymać ładowanie.
foreign keys to columns without a unique keynie jest tworzonyPostgreSQL wymaga klucza unikalnego na kolumnach, do których się odwołuje; InnoDB nie.foreign_key_skipped
table and column namesmałe litery, gdy nazwy pozostają unikalneNazwy z małych liter można w PostgreSQL pisać bez cudzysłowów.identifier_renamed
names over 63 bytesskrócone z hashemNazwy w PostgreSQL mają do 63 bajtów; hash odróżnia skrócone nazwy od siebie.name_shortened
GEOMETRY, POINT, POLYGON...WKB w byteaBez PostGIS standardowy format well-known binary zachowuje dokładnie każdą geometrię.geometry_as_wkb
INET4, INET6, UUID (MariaDB)inet, uuidPostgreSQL ma te same typy.
BINARY, VARBINARY, BLOBbyteaBajty pozostają bajtami.
PARTITION BYjedna tabelaWiersze są te same; jeśli trzeba, podziel tabelę na partycje ponownie w PostgreSQL.partitions_dropped
WITH SYSTEM VERSIONING (MariaDB)tabela z bieżącymi wierszamiZrzut zawiera tylko bieżące wiersze.system_versioning_dropped
MyISAM, MEMORY and other engineszwykła tabelaPostgreSQL ma jeden silnik tabel.engine_dropped
views, triggers, procedures, functions and eventswymienione w raporcieIch kod jest napisany w języku MySQL, więc trafiają na listę do ręcznego odtworzenia.not_converted_objects
dumps without CREATE TABLEtypy odczytane z wartościZrzut zrobiony z --no-create-info zawiera tylko wiersze, więc typy pochodzą z wartości.no_schema
geometries in a dump without CREATE TABLEWKB w byteaFormat geometrii MySQL jest rozpoznawany po wartościach i zapisywany jako standardowe WKB.geometry_inferred
_ci collationsdokładne porównaniePostgreSQL porównuje tekst dokładnie, chyba że ustawisz inaczej.case_insensitive_collation
SET NAMES utf8 from utf8mb4 tablesprzekonwertowane, z ostrzeżeniemmysqldump z MySQL 5.x domyślnie zapisuje 3-bajtowe utf8 i zastępuje każde emoji znakiem zapytania, zanim jakikolwiek konwerter zobaczy plik.dump_lost_four_byte_chars
dumps without SET NAMES whose text isn't UTF-8odczytane jako Latin-1 (Windows-1252)latin1 w MySQL to Windows-1252, zwykłe kodowanie takich zrzutów.charset_guessed
sjis, cp932, gbk, big5 dumpsodczytane jako UTF-8, z ostrzeżeniemTe kodowania nie są jeszcze dekodowane.unsupported_charset
UNHEX('..'), CONVERT(b'..', UNSIGNED), CONVERT(".." USING x), ST_GeomFromText('..') in rowsobliczoneNiektóre narzędzia do zrzutów zapisują wartości jako takie wywołania; są odczytywane jako wartości, które zwracają, przy czym w geograficznym WKT najpierw jest długość geograficzna.
other expressions in rowsNULLKonwerter, który nie uruchamia bazy danych, nie może ich obliczyć.expression_value
DEFAULT in VALUESwartość domyślna kolumnyDosłowna wartość domyślna jest kopiowana do wiersza.default_keyword_filled
DEFAULT in VALUES without a literal defaultNULLNie ma wartości do skopiowania.default_keyword_null
REPLACE and INSERT IGNOREzwykłe wierszeZrzut ma jeden wiersz na klucz, więc wiersze są te same.replace_as_insert
types IntoSQL doesn't knowtextTekst mieści każdą wartość; zmień typ po załadowaniu.unknown_type
values that don't fit their columnNULLUszkodzony lub ręcznie pisany zrzut może zawierać wartości, których kolumna nie przyjmie; stają się NULL, aby reszta się załadowała.invalid_value_null
unreadable geometriesNULLBajtów, które nie są geometrią, nie da się zapisać jako geometrii.bad_geometry
CREATE SEQUENCE (MariaDB)CREATE SEQUENCE z bieżącą wartościąSekwencje w PostgreSQL przyjmują te same opcje.
VECTOR(n) (MariaDB 11.7+)jsonb z liczbami float jako tablicąPostgreSQL bez pgvector nie ma typu wektorowego; tablica JSON zachowuje każdą liczbę float, a rzutowanie jej po załadowaniu na typ vector z pgvector odczytuje ten sam tekst.type_replaced

Załaduj skrypt do PostgreSQL

Skrypt tworzy tabele, kopiuje wiersze, a potem dodaje klucze, indeksy i klucze obce, więc ładuje się szybko i zatrzymuje przy pierwszym błędzie.

psql -v ON_ERROR_STOP=1 -d mydb -f mariadb.postgresql.sql

Klucze obce są dodawane jako NOT VALID, a potem sprawdzane. Jeśli wiersz wskazuje na nieistniejący wiersz, skrypt podaje, którego ograniczenia to dotyczy, zamiast przerwać w połowie.

Przy dużym zrzucie najpierw utwórz bazę danych i uruchom skrypt przez psql na tej samej maszynie co serwer.

IntoSQL Pro ładuje plik prosto do PostgreSQL z aplikacji na komputer lub wiersza poleceń, bez pisania skryptu.

Jak zrobić zrzut MariaDB dla najlepszego wyniku

Konwerter odczytuje to, co zawiera zrzut. Te opcje zachowują w nim więcej twoich danych:

  • --default-character-set=utf8mb4 zachowuje emoji i inne 4-bajtowe znaki, które zrzut utf8mb3 traci, zanim zobaczy go konwerter.
  • --hex-blob zapisuje kolumny binarne i wartości VECTOR szesnastkowo, co przetrwa kopiowanie między systemami.
  • --routines --triggers --events dodają te obiekty do zrzutu, aby raport mógł je wymienić.

Co nie jest konwertowane

Widoki, wyzwalacze, procedury składowane, funkcje i zdarzenia są pisane we własnym języku MariaDB. Raport wymienia je z nazwy i nigdy nie pomija ich po cichu, więc możesz je przepisać dla PostgreSQL.

Pytania o konwersję MariaDB do PostgreSQL

Nie ma tu odpowiedzi? Napisz do nas przez stronę kontaktu, a odpowie człowiek. Strona kontaktu

Czy mój zrzut jest wysyłany?

Nie. Konwerter działa w przeglądarce i odczytuje zrzut z dysku po kawałku, więc nigdy nie opuszcza on twojego komputera. Aplikacja na komputer i wiersz poleceń też konwertują na twoim komputerze.

Jak duży może być zrzut?

Konwerter nigdy nie trzyma całego zrzutu w pamięci: czyta plik dwa razy, fragmentami, i zapisuje skrypt na bieżąco. Zrzuty wielogigabajtowe konwertują się w przeglądarce, w aplikacji na komputer i w wierszu poleceń.

Z jakich wersji MariaDB może pochodzić zrzut?

Zrzuty z mariadb-dump i mysqldump z MariaDB od 10.3 do 12, z jednym INSERT na tabelę lub jednym na wiersz. Każdy testowy zrzut pochodzi z MariaDB 10.11, 11.4 i 11.8 i jest porównywany ze źródłem komórka po komórce.

Czy kolumny UUID, INET6, JSON i VECTOR są zachowywane?

UUID staje się uuid, INET4 i INET6 inet, JSON jsonb, a VECTOR tablicą jsonb jego liczb float. Daty zerowe stają się NULL, a raport je liczy.

Czy wartości AUTO_INCREMENT i sekwencje są zachowywane?

Tak. Każda kolumna AUTO_INCREMENT staje się kolumną identity, która idzie dalej po najwyższym id. Sekwencje stają się sekwencjami PostgreSQL, a wartości domyślne, które z nich pobierają, nadal z nich pobierają.

A procedury składowane i wyzwalacze?

Raport wymienia je z nazwy, ale nie są konwertowane, bo każda baza danych zapisuje je we własnym języku.

Na jakich wersjach PostgreSQL ładuje się skrypt?

PostgreSQL od 13 do 18. Ten sam skrypt ładuje się na każdej z nich i zatrzymuje przy pierwszym błędzie, jeśli coś pójdzie nie tak.