On modeling pairs with a possibly empty second element
Other options I see:

A) add column x to table _data. A few more changes will be required:

CREATE TABLE X (
      x TEXT PRIMARY KEY
);

CREATE TABLE Y (
      y TEXT PRIMARY KEY
    , x TEXT NOT NULL
    , FOREIGN KEY (x) REFERENCES X(x),
    , UNIQUE (x, y)                    -- required for the modified FK below
);

CREATE TABLE _DATA (
      data_id INTEGER PRIMARY KEY
    , x TEXT NOT NULL
    , y TEXT
    , FOREIGN KEY (x, y) REFERENCES Y(x, y)    -- modified FK
    , FOREIGN KEY (x) REFERENCES X(x)          -- additional FK
);


The view has to be modified as well:

CREATE VIEW mydata AS
  SELECT X.x, Y.y
    FROM X JOIN Y     USING (x)
           JOIN _DATA USING (y)
  UNION ALL
  SELECT X.x, NULL
    FROM X JOIN _DATA USING (x) 
  WHERE _DATA.y IS NULL ;


Example:

INSERT INTO X (x) VALUES
    ('a')
  , ('b')
  , ('c')
  , ('d')
;

INSERT INTO Y (y, x) VALUES
    ('h', 'a')
  , ('i', 'b')
  , ('k', 'c')
;

INSERT INTO _DATA (data_id, x, y) VALUES
    (1, 'a', 'h')
  , (2, 'b', 'i')
  , (3, 'b', NULL)
  , (4, 'c', 'k')
  , (5, 'd', NULL)
  , (6, 'a', 'h')
;

SELECT x, y FROM mydata;
 x | y 
---+---
 a | h
 b | i
 c | k
 a | h
 b | 
 d | 
(6 rows)




B) separate the data that have no y value associated to another table. No changes at all required to the existing tables, only for the view:

CREATE TABLE X (
      x TEXT PRIMARY KEY
);

CREATE TABLE Y (
      y TEXT PRIMARY KEY
    , x TEXT NOT NULL
    , FOREIGN KEY (x) REFERENCES X(x)
);

CREATE TABLE _DATA (
      data_id INTEGER PRIMARY KEY
    , y TEXT NOT NULL
    , FOREIGN KEY (y) REFERENCES Y(y)
);

CREATE TABLE _DATA_X (
      data_x_id INTEGER PRIMARY KEY
    , x TEXT NOT NULL
    , FOREIGN KEY (x) REFERENCES X(x)
);


The view modified:

CREATE VIEW mydata AS
  SELECT X.x, Y.y
    FROM X JOIN Y     USING (x)
           JOIN _DATA USING (y)
  UNION ALL
  SELECT X.x, NULL 
    FROM X JOIN _DATA_X USING (x) ;


Example:

INSERT INTO X (x) VALUES
    ('a')
  , ('b')
  , ('c')
  , ('d')
;

INSERT INTO Y (y, x) VALUES
    ('h', 'a')
  , ('i', 'b')
  , ('k', 'c')
;

INSERT INTO _DATA (data_id, y) VALUES
    (1, 'h')
  , (2, 'i')
  , (3, 'k')
  , (4, 'h')
;

INSERT INTO _DATA_X (data_x_id, x) VALUES
    (1, 'b')
  , (2, 'd')
;

SELECT x, y FROM mydata;
 x | y 
---+---
 a | h
 b | i
 c | k
 a | h
 b | 
 d | 
(6 rows)