SingleStore в сравнении с YugabyteDB

Как представитель разработчиков в Yugabyte, я получил несколько вопросов о том, как мы сравниваемся с SingleStore. Есть много простых вещей: YugabyteDB имеет открытый исходный код, совместима с PostgreSQL и является распределенной базой данных SQL. Чтобы убедиться, что SingleStore не относится к категории распределенного SQL, я хотел попробовать свою простую схему SQL, старую схему EMP/DEPT, которая упоминалась в первых статьях о SQL и которая стала легендарной схемой SCOTT в Oracle. Если вы хотите взглянуть на нее, вы можете создать бесплатный кластер YugabyteDB Managed, а учебник поможет вам создать современную версию этой схемы и поиграть с расширенными запросами.

Поскольку я столкнулся с некоторыми ошибками, которые я считаю вводящими в заблуждение, я пишу этот пост в блоге, чтобы помочь в аналогичной ситуации, но вы можете сэкономить время, посмотрев список функций SQL, которые не поддерживаются в SingleStore.

Создание пробной версии SingleStore

Я следовал онлайн-инструкциям, чтобы запустить memsql (внутреннее название SingleStore) с предоставленной пробной лицензией:

docker run -i --init 
    --name memsql-ciab 
    -e LICENSE_KEY="TheLicenceProvidedForTrial0AAAAAAAAAAAEAAAAAAAAACgwNAIYMiZ83R94l1DqqMjt4gqo48F2p4Mm6gAXAhhfuPPKuSmfu3srHlVhoZ2Kspm2o1gz5Y0AAA==" 
    -e ROOT_PASSWORD="admin_p455w0rd" 
    -p 3306:3306 -p 8080:8080 
    memsql/cluster-in-a-box

docker start memsql-ciab
Войдите в полноэкранный режим Выйти из полноэкранного режима

Веб-сайт действительно удобен для создания командной строки, приведенной выше. Разработчики привыкли к Open Source, и необходимость вводить лицензионный ключ обычно делает его менее дружелюбным. Генерация командной строки docker с пробной лицензией — хорошая идея.

Я подключаюсь к ней и запускаю создание таблицы DEPT:

CREATE TABLE dept (
  deptno integer NOT NULL,
  dname text,
  loc text,
  description text,
  CONSTRAINT pk_dept PRIMARY KEY (deptno asc)
);
Войти в полноэкранный режим Выход из полноэкранного режима

Мне повезло, этот синтаксис совместим с MySQL, который во многих случаях может сильно отличаться от стандарта SQL.

Затем я хочу создать таблицу EMP:

CREATE TABLE emp (
  empno integer generated by default as identity (start with 10000) NOT NULL,
  ename text NOT NULL,
  job text,
  mgr integer,
  hiredate date,
  sal integer,
  comm integer,
  deptno integer NOT NULL,
  email text,
  other_info json,
  CONSTRAINT pk_emp PRIMARY KEY (empno hash),
  CONSTRAINT emp_email_uk UNIQUE (email),
  CONSTRAINT fk_deptno FOREIGN KEY (deptno) REFERENCES dept(deptno),
  CONSTRAINT fk_mgr FOREIGN KEY (mgr) REFERENCES emp(empno)
);
Войти в полноэкранный режим Выйти из полноэкранного режима

Это не удается:

ERROR 1064 ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'generated by default as identity (start with 10000) NOT NULL, ename text NOT ' at line 1
Войти в полноэкранный режим Выйти из полноэкранного режима

Я заменяю стандартный SQL генерируемый по умолчанию как identity на auto_increment, к которому привыкли пользователи MySQL

CREATE TABLE emp (
  empno integer  NOT NULL auto_increment,
  ename text NOT NULL,
  job text,
  mgr integer,
  hiredate date,
  sal integer,
  comm integer,
  deptno integer NOT NULL,
  email text,
  other_info json,
  CONSTRAINT pk_emp PRIMARY KEY (empno),
  CONSTRAINT emp_email_uk UNIQUE (email),
  CONSTRAINT fk_deptno FOREIGN KEY (deptno) REFERENCES dept(deptno),
  CONSTRAINT fk_mgr FOREIGN KEY (mgr) REFERENCES emp(empno)
);
Вход в полноэкранный режим Выйти из полноэкранного режима

При этом происходит сбой:

ERROR 1706 ER_MEMSQL_FEATURE_LOCKDOWN: Feature 'FOREIGN KEY on COLUMNAR table' is not supported by SingleStore.
Войти в полноэкранный режим Выйти из полноэкранного режима

Хорошо, давайте пересоздадим таблицу как ROWSTORE таблицу, что имеет смысл для OLTP:

DROP TABLE dept;
CREATE ROWSTORE TABLE dept (
  deptno integer NOT NULL,
  dname text,
  loc text,
  description text,
  CONSTRAINT pk_dept PRIMARY KEY (deptno asc)
);
CREATE ROWSTORE TABLE emp (
  empno integer  NOT NULL auto_increment,
  ename text NOT NULL,
  job text,
  mgr integer,
  hiredate date,
  sal integer,
  comm integer,
  deptno integer NOT NULL,
  email text,
  other_info json,
  CONSTRAINT pk_emp PRIMARY KEY (empno),
  CONSTRAINT emp_email_uk UNIQUE (email),
  CONSTRAINT fk_deptno FOREIGN KEY (deptno) REFERENCES dept(deptno),
  CONSTRAINT fk_mgr FOREIGN KEY (mgr) REFERENCES emp(empno)
);
Войти в полноэкранный режим Выйти из полноэкранного режима

Теперь другая ошибка по-прежнему препятствует ссылочной целостности:

ERROR 1706 ER_MEMSQL_FEATURE_LOCKDOWN: Feature 'FOREIGN (non-SHARD) key to a sharded table' is not supported by SingleStore.
Войти в полноэкранный режим Выйти из полноэкранного режима

Таким образом, ссылочная таблица не может быть разделена на части. Нет проблем, это все равно ссылочная таблица, давайте создадим ее как REFERENCE:

DROP TABLE dept;
CREATE ROWSTORE REFERENCE TABLE dept (
  deptno integer NOT NULL,
  dname text,
  loc text,
  description text,
  CONSTRAINT pk_dept PRIMARY KEY (deptno asc)
);
CREATE ROWSTORE TABLE emp (
  empno integer  NOT NULL auto_increment,
  ename text NOT NULL,
  job text,
  mgr integer,
  hiredate date,
  sal integer,
  comm integer,
  deptno integer NOT NULL,
  email text,
  other_info json,
  CONSTRAINT pk_emp PRIMARY KEY (empno),
  CONSTRAINT emp_email_uk UNIQUE (email),
  CONSTRAINT fk_deptno FOREIGN KEY (deptno) REFERENCES dept(deptno),
  CONSTRAINT fk_mgr FOREIGN KEY (mgr) REFERENCES emp(empno)
);
Войти в полноэкранный режим Выход из полноэкранного режима

Но это снова не удается:

ERROR 1706 ER_MEMSQL_FEATURE_LOCKDOWN: Feature 'FOREIGN (non-SHARD) key to a sharded table' is not supported by SingleStore.
Войти в полноэкранный режим Выход из полноэкранного режима

Вы можете подумать, что это из-за самоссылки fk_mgr FOREIGN KEY (mgr) REFERENCES emp(empno), но я получил ту же ошибку при ее удалении. Давайте удалим оба внешних ключа:


CREATE ROWSTORE TABLE emp (
  empno integer  NOT NULL auto_increment,
  ename text NOT NULL,
  job text,
  mgr integer,
  hiredate date,
  sal integer,
  comm integer,
  deptno integer NOT NULL,
  email text,
  other_info json,
  CONSTRAINT pk_emp PRIMARY KEY (empno),
  CONSTRAINT emp_email_uk UNIQUE (email)-- ,
  -- CONSTRAINT fk_deptno FOREIGN KEY (deptno) REFERENCES dept(deptno),
  -- CONSTRAINT fk_mgr FOREIGN KEY (mgr) REFERENCES emp(empno)
);
Войдите в полноэкранный режим Выход из полноэкранного режима

(обратите внимание, что пробел после -- является обязательным в MySQL)

Это не удается при другом ограничении:

ERROR 1895 ER_MEMSQL_UNIQUE_KEY_IMPLICIT_SHARD_KEY: The unique key named: 'emp_email_uk' must contain all columns specified in the primary key when no shard key is declared
Войти в полноэкранный режим Выход из полноэкранного режима

Глобальное уникальное ограничение также не поддерживается. Это фундаментальная особенность SQL. В реальной жизни большинство таблиц имеют один или несколько уникальных естественных ключей в дополнение к сгенерированному первичному ключу. Очень важно обеспечить уникальность, потому что это единственный способ предотвратить дублирование. Это очень важно для облачных приложений с высокой доступностью, где в случае сбоя приложение не знает, произошел ли сбой в сети до или после фиксации. Первичный ключ часто генерируется приложением. Только естественный ключ может предотвратить двойную вставку.

Ну, слишком много ограничений, я могу запустить свой простой CREATE только тогда, когда обе таблицы являются REFERENCE:

DROP TABLE dept;
CREATE ROWSTORE REFERENCE TABLE dept (
  deptno integer NOT NULL,
  dname text,
  loc text,
  description text,
  CONSTRAINT pk_dept PRIMARY KEY (deptno asc)
);
CREATE ROWSTORE REFERENCE TABLE emp (
  empno integer  NOT NULL auto_increment,
  ename text NOT NULL,
  job text,
  mgr integer,
  hiredate date,
  sal integer,
  comm integer,
  deptno integer NOT NULL,
  email text,
  other_info json,
  CONSTRAINT pk_emp PRIMARY KEY (empno),
  CONSTRAINT emp_email_uk UNIQUE (email),
  CONSTRAINT fk_deptno FOREIGN KEY (deptno) REFERENCES dept(deptno),
  CONSTRAINT fk_mgr FOREIGN KEY (mgr) REFERENCES emp(empno)
);
Войти в полноэкранный режим Выйти из полноэкранного режима

*Это наконец-то работает. Но… Я больше не в распределенной базе данных, так как ни одна таблица не разделена на шарды. *

Вставить

В моей таблице без шардинга я продолжаю вставлять строки образца

INSERT INTO dept (deptno,  dname,        loc, description)
     VALUES    (10,     'ACCOUNTING', 'NEW YORK','preparation of financial statements, maintenance of general ledger, payment of bills, preparation of customer bills, payroll, and more.'),
            (20,     'RESEARCH',   'DALLAS','responsible for preparing the substance of a research report or security recommendation.'),
            (30,     'SALES',      'CHICAGO','division of a business that is responsible for selling products or services'),
            (40,     'OPERATIONS', 'BOSTON','administration of business practices to create the highest level of efficiency possible within an organization');

INSERT INTO emp (empno, ename,    job,        mgr,   hiredate,     sal, comm, deptno, email, other_info)
     VALUES   (7369, 'SMITH',  'CLERK',     7902, '1980-12-17',  800, NULL,   20,'SMITH@acme.com', '{"skills":["accounting"]}'),
            (7499, 'ALLEN',  'SALESMAN',  7698, '1981-02-20', 1600,  300,   30,'ALLEN@acme.com', null),
            (7521, 'WARD',   'SALESMAN',  7698, '1981-02-22', 1250,  500,   30,'WARD@compuserve.com', null),
            (7566, 'JONES',  'MANAGER',   7839, '1981-04-02', 2975, NULL,   20,'JONES@gmail.com', null),
            (7654, 'MARTIN', 'SALESMAN',  7698, '1981-09-28', 1250, 1400,   30,'MARTIN@acme.com', null),
            (7698, 'BLAKE',  'MANAGER',   7839, '1981-05-01', 2850, NULL,   30,'BLAKE@hotmail.com', null),
            (7782, 'CLARK',  'MANAGER',   7839, '1981-06-09', 2450, NULL,   10,'CLARK@acme.com', '{"skills":["C","C++","SQL"]}'),
            (7788, 'SCOTT',  'ANALYST',   7566, '1982-12-09', 3000, NULL,   20,'SCOTT@acme.com', '{"cat":"tiger"}'),
            (7839, 'KING',   'PRESIDENT', NULL, '1981-11-17', 5000, NULL,   10,'KING@aol.com', null),
            (7844, 'TURNER', 'SALESMAN',  7698, '1981-09-08', 1500,    0,   30,'TURNER@acme.com', null),
            (7876, 'ADAMS',  'CLERK',     7788, '1983-01-12', 1100, NULL,   20,'ADAMS@acme.org', null),
            (7900, 'JAMES',  'CLERK',     7698, '1981-12-03',  950, NULL,   30,'JAMES@acme.org', null),
            (7902, 'FORD',   'ANALYST',   7566, '1981-12-03', 3000, NULL,   20,'FORD@acme.com', '{"skills":["SQL","CQL"]}'),
            (7934, 'MILLER', 'CLERK',     7782, '1982-01-23', 1300, NULL,   10,'MILLER@acme.com', null);

Вход в полноэкранный режим Выйти из полноэкранного режима

Это работает без проблем.

Однако давайте попробуем удалить отдел, в котором содержатся сотрудники:


> delete from dept where deptno=10;

Query OK, 1 row affected (372 ms)

> select * from dept;
+---------------------------------------------------------------------------------------------------------------------------+
| deptno                       | dname                        | loc                          | description                  |
+---------------------------------------------------------------------------------------------------------------------------+
| 20                           | RESEARCH                     | DALLAS                       | responsible for preparing ...|
| 30                           | SALES                        | CHICAGO                      | division of a business tha...|
| 40                           | OPERATIONS                   | BOSTON                       | administration of business...|
+---------------------------------------------------------------------------------------------------------------------------+

3 rows in set (110 ms)

> select deptno, count(*) from emp group by deptno order by 1;
+-------------------------------------------------------------+
| deptno                       | count(*)                     |
+-------------------------------------------------------------+
| 10                           | 3                            |
| 20                           | 5                            |
| 30                           | 6                            |
+-------------------------------------------------------------+

3 rows in set (75 ms)

Войти в полноэкранный режим Выход из полноэкранного режима

При отсутствии шардинга я смог создать внешний ключ, но он бесполезен, так как ничего не защищает. Теперь у меня есть несколько сотрудников в несуществующем отделе.

Я сделал это, чтобы убедиться, что SingleStore не является распределенной базой данных SQL, как базы данных на основе Spanner, которые распределяют все возможности SQL со всеми свойствами ACID в кросс-шардированных транзакциях. Но у SingleStore есть свои сценарии использования, и она является основным действующим лицом в облачных базах данных NewSQL, особенно в аналитике, благодаря своему хранилищу столбцов по умолчанию.

Оцените статью
devanswers.ru
Добавить комментарий